@drift-labs/sdk 2.87.0-beta.7 → 2.87.0-beta.9

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/VERSION CHANGED
@@ -1 +1 @@
1
- 2.87.0-beta.7
1
+ 2.87.0-beta.9
package/lib/config.d.ts CHANGED
@@ -11,6 +11,7 @@ type DriftConfig = {
11
11
  USDC_MINT_ADDRESS: string;
12
12
  SERUM_V3: string;
13
13
  PHOENIX: string;
14
+ OPENBOOK: string;
14
15
  V2_ALPHA_TICKET_MINT_ADDRESS: string;
15
16
  PERP_MARKETS: PerpMarketConfig[];
16
17
  SPOT_MARKETS: SpotMarketConfig[];
package/lib/config.js CHANGED
@@ -14,6 +14,7 @@ exports.configs = {
14
14
  USDC_MINT_ADDRESS: '8zGuJQqwhZafTah7Uc7Z4tXRnguqkn5KLFAP8oV6PHe2',
15
15
  SERUM_V3: 'DESVgJVGajEgKGXhb6XmqDHGz3VjdgP7rEVESBgxmroY',
16
16
  PHOENIX: 'PhoeNiXZ8ByJGLkxNfZRnkUfjvmuYqLR89jjFHGqdXY',
17
+ OPENBOOK: 'opnb2LAfJYbRMAHHvqjCwQxanZn7ReEHp1k81EohpZb',
17
18
  V2_ALPHA_TICKET_MINT_ADDRESS: 'DeEiGWfCMP9psnLGkxGrBBMEAW5Jv8bBGMN8DCtFRCyB',
18
19
  PERP_MARKETS: perpMarkets_1.DevnetPerpMarkets,
19
20
  SPOT_MARKETS: spotMarkets_1.DevnetSpotMarkets,
@@ -28,6 +29,7 @@ exports.configs = {
28
29
  USDC_MINT_ADDRESS: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
29
30
  SERUM_V3: 'srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX',
30
31
  PHOENIX: 'PhoeNiXZ8ByJGLkxNfZRnkUfjvmuYqLR89jjFHGqdXY',
32
+ OPENBOOK: 'opnb2LAfJYbRMAHHvqjCwQxanZn7ReEHp1k81EohpZb',
31
33
  V2_ALPHA_TICKET_MINT_ADDRESS: 'Cmvhycb6LQvvzaShGw4iDHRLzeSSryioAsU98DSSkMNa',
32
34
  PERP_MARKETS: perpMarkets_1.MainnetPerpMarkets,
33
35
  SPOT_MARKETS: spotMarkets_1.MainnetSpotMarkets,
@@ -11,6 +11,7 @@ export type SpotMarketConfig = {
11
11
  precisionExp: BN;
12
12
  serumMarket?: PublicKey;
13
13
  phoenixMarket?: PublicKey;
14
+ openbookMarket?: PublicKey;
14
15
  launchTs?: number;
15
16
  pythFeedId?: string;
16
17
  };
@@ -250,6 +250,7 @@ export declare class DriftClient {
250
250
  signers: Signer[];
251
251
  pubkey: PublicKey;
252
252
  }>;
253
+ getTokenProgramForSpotMarket(spotMarketAccount: SpotMarketAccount): PublicKey;
253
254
  addTokenMintToRemainingAccounts(spotMarketAccount: SpotMarketAccount, remainingAccounts: AccountMeta[]): void;
254
255
  getAssociatedTokenAccountCreationIx(tokenMintAddress: PublicKey, associatedTokenAddress: PublicKey): anchor.web3.TransactionInstruction;
255
256
  createInitializeUserAccountAndDepositCollateral(amount: BN, userTokenAccount: PublicKey, marketIndex?: number, subAccountId?: number, name?: string, fromSubAccountId?: number, referrerInfo?: ReferrerInfo, donateAmount?: BN, txParams?: TxParams, customMaxMarginRatio?: number): Promise<[Transaction | VersionedTransaction, PublicKey]>;
@@ -640,6 +641,8 @@ export declare class DriftClient {
640
641
  settleMultiplePNLsIx(settleeUserAccountPublicKey: PublicKey, settleeUserAccount: UserAccount, marketIndexes: number[], mode: SettlePnlMode): Promise<TransactionInstruction>;
641
642
  liquidatePerp(userAccountPublicKey: PublicKey, userAccount: UserAccount, marketIndex: number, maxBaseAssetAmount: BN, limitPrice?: BN, txParams?: TxParams, liquidatorSubAccountId?: number): Promise<TransactionSignature>;
642
643
  getLiquidatePerpIx(userAccountPublicKey: PublicKey, userAccount: UserAccount, marketIndex: number, maxBaseAssetAmount: BN, limitPrice?: BN, liquidatorSubAccountId?: number): Promise<TransactionInstruction>;
644
+ liquidatePerpWithFill(userAccountPublicKey: PublicKey, userAccount: UserAccount, marketIndex: number, makerInfos: MakerInfo[], txParams?: TxParams, liquidatorSubAccountId?: number): Promise<TransactionSignature>;
645
+ getLiquidatePerpWithFillIx(userAccountPublicKey: PublicKey, userAccount: UserAccount, marketIndex: number, makerInfos: MakerInfo[], liquidatorSubAccountId?: number): Promise<TransactionInstruction>;
643
646
  liquidateSpot(userAccountPublicKey: PublicKey, userAccount: UserAccount, assetMarketIndex: number, liabilityMarketIndex: number, maxLiabilityTransfer: BN, limitPrice?: BN, txParams?: TxParams, liquidatorSubAccountId?: number): Promise<TransactionSignature>;
644
647
  getLiquidateSpotIx(userAccountPublicKey: PublicKey, userAccount: UserAccount, assetMarketIndex: number, liabilityMarketIndex: number, maxLiabilityTransfer: BN, limitPrice?: BN, liquidatorSubAccountId?: number): Promise<TransactionInstruction>;
645
648
  liquidateBorrowForPerpPnl(userAccountPublicKey: PublicKey, userAccount: UserAccount, perpMarketIndex: number, liabilityMarketIndex: number, maxLiabilityTransfer: BN, limitPrice?: BN, txParams?: TxParams, liquidatorSubAccountId?: number): Promise<TransactionSignature>;
@@ -52,7 +52,6 @@ const spotPosition_1 = require("./math/spotPosition");
52
52
  const market_1 = require("./math/market");
53
53
  const fetch_1 = require("./accounts/fetch");
54
54
  const spotMarket_1 = require("./math/spotMarket");
55
- const pda_2 = require("./addresses/pda");
56
55
  const memcmp_1 = require("./memcmp");
57
56
  const marinade_1 = require("./marinade");
58
57
  const orderParams_1 = require("./orderParams");
@@ -1135,7 +1134,7 @@ class DriftClient {
1135
1134
  }
1136
1135
  const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
1137
1136
  this.addTokenMintToRemainingAccounts(spotMarketAccount, remainingAccounts);
1138
- const tokenProgram = (0, pda_2.getTokenProgramForSpotMarket)(spotMarketAccount);
1137
+ const tokenProgram = this.getTokenProgramForSpotMarket(spotMarketAccount);
1139
1138
  return await this.program.instruction.deposit(marketIndex, amount, reduceOnly, {
1140
1139
  accounts: {
1141
1140
  state: await this.getStatePublicKey(),
@@ -1187,6 +1186,12 @@ class DriftClient {
1187
1186
  result.ixs.push((0, spl_token_1.createInitializeAccountInstruction)(wrappedSolAccount, spotMarkets_1.WRAPPED_SOL_MINT, authority));
1188
1187
  return result;
1189
1188
  }
1189
+ getTokenProgramForSpotMarket(spotMarketAccount) {
1190
+ if (spotMarketAccount.tokenProgram === 1) {
1191
+ return spl_token_1.TOKEN_2022_PROGRAM_ID;
1192
+ }
1193
+ return spl_token_1.TOKEN_PROGRAM_ID;
1194
+ }
1190
1195
  addTokenMintToRemainingAccounts(spotMarketAccount, remainingAccounts) {
1191
1196
  if (spotMarketAccount.tokenProgram === 1) {
1192
1197
  remainingAccounts.push({
@@ -1360,7 +1365,7 @@ class DriftClient {
1360
1365
  });
1361
1366
  const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
1362
1367
  this.addTokenMintToRemainingAccounts(spotMarketAccount, remainingAccounts);
1363
- const tokenProgram = (0, pda_2.getTokenProgramForSpotMarket)(spotMarketAccount);
1368
+ const tokenProgram = this.getTokenProgramForSpotMarket(spotMarketAccount);
1364
1369
  return await this.program.instruction.withdraw(marketIndex, amount, reduceOnly, {
1365
1370
  accounts: {
1366
1371
  state: await this.getStatePublicKey(),
@@ -2371,7 +2376,7 @@ class DriftClient {
2371
2376
  outAssociatedTokenAccount = await this.getAssociatedTokenAccount(outMarket.marketIndex, false);
2372
2377
  const accountInfo = await this.connection.getAccountInfo(outAssociatedTokenAccount);
2373
2378
  if (!accountInfo) {
2374
- const tokenProgram = (0, pda_2.getTokenProgramForSpotMarket)(outMarket);
2379
+ const tokenProgram = this.getTokenProgramForSpotMarket(outMarket);
2375
2380
  preInstructions.push(this.createAssociatedTokenAccountIdempotentInstruction(outAssociatedTokenAccount, this.provider.wallet.publicKey, this.provider.wallet.publicKey, outMarket.mint, tokenProgram));
2376
2381
  }
2377
2382
  }
@@ -2379,7 +2384,7 @@ class DriftClient {
2379
2384
  inAssociatedTokenAccount = await this.getAssociatedTokenAccount(inMarket.marketIndex, false);
2380
2385
  const accountInfo = await this.connection.getAccountInfo(inAssociatedTokenAccount);
2381
2386
  if (!accountInfo) {
2382
- const tokenProgram = (0, pda_2.getTokenProgramForSpotMarket)(outMarket);
2387
+ const tokenProgram = this.getTokenProgramForSpotMarket(outMarket);
2383
2388
  preInstructions.push(this.createAssociatedTokenAccountIdempotentInstruction(inAssociatedTokenAccount, this.provider.wallet.publicKey, this.provider.wallet.publicKey, inMarket.mint, tokenProgram));
2384
2389
  }
2385
2390
  }
@@ -2495,8 +2500,8 @@ class DriftClient {
2495
2500
  });
2496
2501
  const outSpotMarket = this.getSpotMarketAccount(outMarketIndex);
2497
2502
  const inSpotMarket = this.getSpotMarketAccount(inMarketIndex);
2498
- const outTokenProgram = (0, pda_2.getTokenProgramForSpotMarket)(outSpotMarket);
2499
- const inTokenProgram = (0, pda_2.getTokenProgramForSpotMarket)(inSpotMarket);
2503
+ const outTokenProgram = this.getTokenProgramForSpotMarket(outSpotMarket);
2504
+ const inTokenProgram = this.getTokenProgramForSpotMarket(inSpotMarket);
2500
2505
  if (!outTokenProgram.equals(inTokenProgram)) {
2501
2506
  remainingAccounts.push({
2502
2507
  pubkey: outTokenProgram,
@@ -3228,6 +3233,44 @@ class DriftClient {
3228
3233
  remainingAccounts: remainingAccounts,
3229
3234
  });
3230
3235
  }
3236
+ async liquidatePerpWithFill(userAccountPublicKey, userAccount, marketIndex, makerInfos, txParams, liquidatorSubAccountId) {
3237
+ const { txSig, slot } = await this.sendTransaction(await this.buildTransaction(await this.getLiquidatePerpWithFillIx(userAccountPublicKey, userAccount, marketIndex, makerInfos, liquidatorSubAccountId), txParams), [], this.opts);
3238
+ this.perpMarketLastSlotCache.set(marketIndex, slot);
3239
+ return txSig;
3240
+ }
3241
+ async getLiquidatePerpWithFillIx(userAccountPublicKey, userAccount, marketIndex, makerInfos, liquidatorSubAccountId) {
3242
+ const userStatsPublicKey = (0, pda_1.getUserStatsAccountPublicKey)(this.program.programId, userAccount.authority);
3243
+ const liquidator = await this.getUserAccountPublicKey(liquidatorSubAccountId);
3244
+ const liquidatorStatsPublicKey = this.getUserStatsAccountPublicKey();
3245
+ const remainingAccounts = this.getRemainingAccounts({
3246
+ userAccounts: [this.getUserAccount(liquidatorSubAccountId), userAccount],
3247
+ useMarketLastSlotCache: true,
3248
+ writablePerpMarketIndexes: [marketIndex],
3249
+ });
3250
+ for (const makerInfo of makerInfos) {
3251
+ remainingAccounts.push({
3252
+ pubkey: makerInfo.maker,
3253
+ isSigner: false,
3254
+ isWritable: true,
3255
+ });
3256
+ remainingAccounts.push({
3257
+ pubkey: makerInfo.makerStats,
3258
+ isSigner: false,
3259
+ isWritable: true,
3260
+ });
3261
+ }
3262
+ return await this.program.instruction.liquidatePerpWithFill(marketIndex, {
3263
+ accounts: {
3264
+ state: await this.getStatePublicKey(),
3265
+ authority: this.wallet.publicKey,
3266
+ user: userAccountPublicKey,
3267
+ userStats: userStatsPublicKey,
3268
+ liquidator,
3269
+ liquidatorStats: liquidatorStatsPublicKey,
3270
+ },
3271
+ remainingAccounts: remainingAccounts,
3272
+ });
3273
+ }
3231
3274
  async liquidateSpot(userAccountPublicKey, userAccount, assetMarketIndex, liabilityMarketIndex, maxLiabilityTransfer, limitPrice, txParams, liquidatorSubAccountId) {
3232
3275
  const { txSig, slot } = await this.sendTransaction(await this.buildTransaction(await this.getLiquidateSpotIx(userAccountPublicKey, userAccount, assetMarketIndex, liabilityMarketIndex, maxLiabilityTransfer, limitPrice, liquidatorSubAccountId), txParams), [], this.opts);
3233
3276
  this.spotMarketLastSlotCache.set(assetMarketIndex, slot);
@@ -3487,7 +3530,7 @@ class DriftClient {
3487
3530
  const ifStakeAccountPublicKey = (0, pda_1.getInsuranceFundStakeAccountPublicKey)(this.program.programId, this.wallet.publicKey, marketIndex);
3488
3531
  const remainingAccounts = [];
3489
3532
  this.addTokenMintToRemainingAccounts(spotMarket, remainingAccounts);
3490
- const tokenProgram = (0, pda_2.getTokenProgramForSpotMarket)(spotMarket);
3533
+ const tokenProgram = this.getTokenProgramForSpotMarket(spotMarket);
3491
3534
  const ix = this.program.instruction.addInsuranceFundStake(marketIndex, amount, {
3492
3535
  accounts: {
3493
3536
  state: await this.getStatePublicKey(),
@@ -3604,7 +3647,7 @@ class DriftClient {
3604
3647
  }
3605
3648
  const remainingAccounts = [];
3606
3649
  this.addTokenMintToRemainingAccounts(spotMarketAccount, remainingAccounts);
3607
- const tokenProgram = (0, pda_2.getTokenProgramForSpotMarket)(spotMarketAccount);
3650
+ const tokenProgram = this.getTokenProgramForSpotMarket(spotMarketAccount);
3608
3651
  const removeStakeIx = await this.program.instruction.removeInsuranceFundStake(marketIndex, {
3609
3652
  accounts: {
3610
3653
  state: await this.getStatePublicKey(),
@@ -3678,7 +3721,7 @@ class DriftClient {
3678
3721
  const spotMarket = await this.getSpotMarketAccount(marketIndex);
3679
3722
  const remainingAccounts = [];
3680
3723
  this.addTokenMintToRemainingAccounts(spotMarket, remainingAccounts);
3681
- const tokenProgram = (0, pda_2.getTokenProgramForSpotMarket)(spotMarket);
3724
+ const tokenProgram = this.getTokenProgramForSpotMarket(spotMarket);
3682
3725
  const ix = await this.program.instruction.depositIntoSpotMarketRevenuePool(amount, {
3683
3726
  accounts: {
3684
3727
  state: await this.getStatePublicKey(),
@@ -1675,6 +1675,47 @@
1675
1675
  }
1676
1676
  ]
1677
1677
  },
1678
+ {
1679
+ "name": "liquidatePerpWithFill",
1680
+ "accounts": [
1681
+ {
1682
+ "name": "state",
1683
+ "isMut": false,
1684
+ "isSigner": false
1685
+ },
1686
+ {
1687
+ "name": "authority",
1688
+ "isMut": false,
1689
+ "isSigner": true
1690
+ },
1691
+ {
1692
+ "name": "liquidator",
1693
+ "isMut": true,
1694
+ "isSigner": false
1695
+ },
1696
+ {
1697
+ "name": "liquidatorStats",
1698
+ "isMut": true,
1699
+ "isSigner": false
1700
+ },
1701
+ {
1702
+ "name": "user",
1703
+ "isMut": true,
1704
+ "isSigner": false
1705
+ },
1706
+ {
1707
+ "name": "userStats",
1708
+ "isMut": true,
1709
+ "isSigner": false
1710
+ }
1711
+ ],
1712
+ "args": [
1713
+ {
1714
+ "name": "marketIndex",
1715
+ "type": "u16"
1716
+ }
1717
+ ]
1718
+ },
1678
1719
  {
1679
1720
  "name": "liquidateSpot",
1680
1721
  "accounts": [
@@ -3362,27 +3403,6 @@
3362
3403
  }
3363
3404
  ]
3364
3405
  },
3365
- {
3366
- "name": "initializePredictionMarket",
3367
- "accounts": [
3368
- {
3369
- "name": "admin",
3370
- "isMut": false,
3371
- "isSigner": true
3372
- },
3373
- {
3374
- "name": "state",
3375
- "isMut": false,
3376
- "isSigner": false
3377
- },
3378
- {
3379
- "name": "perpMarket",
3380
- "isMut": true,
3381
- "isSigner": false
3382
- }
3383
- ],
3384
- "args": []
3385
- },
3386
3406
  {
3387
3407
  "name": "deleteInitializedPerpMarket",
3388
3408
  "accounts": [
@@ -9858,6 +9878,9 @@
9858
9878
  },
9859
9879
  {
9860
9880
  "name": "PlaceAndTake"
9881
+ },
9882
+ {
9883
+ "name": "Liquidation"
9861
9884
  }
9862
9885
  ]
9863
9886
  }
@@ -10125,9 +10148,6 @@
10125
10148
  },
10126
10149
  {
10127
10150
  "name": "Future"
10128
- },
10129
- {
10130
- "name": "Prediction"
10131
10151
  }
10132
10152
  ]
10133
10153
  }
@@ -12797,6 +12817,11 @@
12797
12817
  "code": 6282,
12798
12818
  "name": "NonZeroTransferFee",
12799
12819
  "msg": "Non zero transfer fee"
12820
+ },
12821
+ {
12822
+ "code": 6283,
12823
+ "name": "LiquidationOrderFailedToFill",
12824
+ "msg": "Liquidation order failed to fill"
12800
12825
  }
12801
12826
  ],
12802
12827
  "metadata": {
@@ -27,8 +27,8 @@ export declare class OpenbookV2Subscriber implements L2OrderBookGenerator {
27
27
  client: OpenBookV2Client;
28
28
  constructor(config: OpenbookV2SubscriberConfig);
29
29
  subscribe(): Promise<void>;
30
- getBestBid(): Promise<BN | undefined>;
31
- getBestAsk(): Promise<BN | undefined>;
30
+ getBestBid(): BN | undefined;
31
+ getBestAsk(): BN | undefined;
32
32
  getL2Bids(): Generator<L2Level>;
33
33
  getL2Asks(): Generator<L2Level>;
34
34
  getL2Levels(side: 'bids' | 'asks'): Generator<L2Level>;
@@ -50,17 +50,15 @@ class OpenbookV2Subscriber {
50
50
  }
51
51
  this.subscribed = true;
52
52
  }
53
- async getBestBid() {
54
- const bids = await this.market.loadBids();
55
- const bestBid = bids.best();
53
+ getBestBid() {
54
+ const bestBid = this.market.bids.best();
56
55
  if (bestBid === undefined) {
57
56
  return undefined;
58
57
  }
59
58
  return new anchor_1.BN(Math.floor(bestBid.price * numericConstants_1.PRICE_PRECISION.toNumber()));
60
59
  }
61
- async getBestAsk() {
62
- const asks = await this.market.loadAsks();
63
- const bestAsk = asks.best();
60
+ getBestAsk() {
61
+ const bestAsk = this.market.asks.best();
64
62
  if (bestAsk === undefined) {
65
63
  return undefined;
66
64
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/sdk",
3
- "version": "2.87.0-beta.7",
3
+ "version": "2.87.0-beta.9",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "author": "crispheaney",
package/src/config.ts CHANGED
@@ -23,6 +23,7 @@ type DriftConfig = {
23
23
  USDC_MINT_ADDRESS: string;
24
24
  SERUM_V3: string;
25
25
  PHOENIX: string;
26
+ OPENBOOK: string;
26
27
  V2_ALPHA_TICKET_MINT_ADDRESS: string;
27
28
  PERP_MARKETS: PerpMarketConfig[];
28
29
  SPOT_MARKETS: SpotMarketConfig[];
@@ -46,6 +47,7 @@ export const configs: { [key in DriftEnv]: DriftConfig } = {
46
47
  USDC_MINT_ADDRESS: '8zGuJQqwhZafTah7Uc7Z4tXRnguqkn5KLFAP8oV6PHe2',
47
48
  SERUM_V3: 'DESVgJVGajEgKGXhb6XmqDHGz3VjdgP7rEVESBgxmroY',
48
49
  PHOENIX: 'PhoeNiXZ8ByJGLkxNfZRnkUfjvmuYqLR89jjFHGqdXY',
50
+ OPENBOOK: 'opnb2LAfJYbRMAHHvqjCwQxanZn7ReEHp1k81EohpZb',
49
51
  V2_ALPHA_TICKET_MINT_ADDRESS:
50
52
  'DeEiGWfCMP9psnLGkxGrBBMEAW5Jv8bBGMN8DCtFRCyB',
51
53
  PERP_MARKETS: DevnetPerpMarkets,
@@ -61,6 +63,7 @@ export const configs: { [key in DriftEnv]: DriftConfig } = {
61
63
  USDC_MINT_ADDRESS: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
62
64
  SERUM_V3: 'srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX',
63
65
  PHOENIX: 'PhoeNiXZ8ByJGLkxNfZRnkUfjvmuYqLR89jjFHGqdXY',
66
+ OPENBOOK: 'opnb2LAfJYbRMAHHvqjCwQxanZn7ReEHp1k81EohpZb',
64
67
  V2_ALPHA_TICKET_MINT_ADDRESS:
65
68
  'Cmvhycb6LQvvzaShGw4iDHRLzeSSryioAsU98DSSkMNa',
66
69
  PERP_MARKETS: MainnetPerpMarkets,
@@ -20,6 +20,7 @@ export type SpotMarketConfig = {
20
20
  precisionExp: BN;
21
21
  serumMarket?: PublicKey;
22
22
  phoenixMarket?: PublicKey;
23
+ openbookMarket?: PublicKey;
23
24
  launchTs?: number;
24
25
  pythFeedId?: string;
25
26
  };
@@ -14,6 +14,7 @@ import {
14
14
  createInitializeAccountInstruction,
15
15
  getAssociatedTokenAddress,
16
16
  TOKEN_PROGRAM_ID,
17
+ TOKEN_2022_PROGRAM_ID,
17
18
  } from '@solana/spl-token';
18
19
  import {
19
20
  StateAccount,
@@ -119,7 +120,6 @@ import { isSpotPositionAvailable } from './math/spotPosition';
119
120
  import { calculateMarketMaxAvailableInsurance } from './math/market';
120
121
  import { fetchUserStatsAccount } from './accounts/fetch';
121
122
  import { castNumberToSpotPrecision } from './math/spotMarket';
122
- import { getTokenProgramForSpotMarket } from './addresses/pda';
123
123
  import {
124
124
  JupiterClient,
125
125
  QuoteResponse,
@@ -1973,7 +1973,7 @@ export class DriftClient {
1973
1973
  const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
1974
1974
 
1975
1975
  this.addTokenMintToRemainingAccounts(spotMarketAccount, remainingAccounts);
1976
- const tokenProgram = getTokenProgramForSpotMarket(spotMarketAccount);
1976
+ const tokenProgram = this.getTokenProgramForSpotMarket(spotMarketAccount);
1977
1977
  return await this.program.instruction.deposit(
1978
1978
  marketIndex,
1979
1979
  amount,
@@ -2060,6 +2060,15 @@ export class DriftClient {
2060
2060
  return result;
2061
2061
  }
2062
2062
 
2063
+ public getTokenProgramForSpotMarket(
2064
+ spotMarketAccount: SpotMarketAccount
2065
+ ): PublicKey {
2066
+ if (spotMarketAccount.tokenProgram === 1) {
2067
+ return TOKEN_2022_PROGRAM_ID;
2068
+ }
2069
+ return TOKEN_PROGRAM_ID;
2070
+ }
2071
+
2063
2072
  public addTokenMintToRemainingAccounts(
2064
2073
  spotMarketAccount: SpotMarketAccount,
2065
2074
  remainingAccounts: AccountMeta[]
@@ -2486,7 +2495,7 @@ export class DriftClient {
2486
2495
  const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
2487
2496
 
2488
2497
  this.addTokenMintToRemainingAccounts(spotMarketAccount, remainingAccounts);
2489
- const tokenProgram = getTokenProgramForSpotMarket(spotMarketAccount);
2498
+ const tokenProgram = this.getTokenProgramForSpotMarket(spotMarketAccount);
2490
2499
 
2491
2500
  return await this.program.instruction.withdraw(
2492
2501
  marketIndex,
@@ -4250,7 +4259,7 @@ export class DriftClient {
4250
4259
  outAssociatedTokenAccount
4251
4260
  );
4252
4261
  if (!accountInfo) {
4253
- const tokenProgram = getTokenProgramForSpotMarket(outMarket);
4262
+ const tokenProgram = this.getTokenProgramForSpotMarket(outMarket);
4254
4263
 
4255
4264
  preInstructions.push(
4256
4265
  this.createAssociatedTokenAccountIdempotentInstruction(
@@ -4274,7 +4283,7 @@ export class DriftClient {
4274
4283
  inAssociatedTokenAccount
4275
4284
  );
4276
4285
  if (!accountInfo) {
4277
- const tokenProgram = getTokenProgramForSpotMarket(outMarket);
4286
+ const tokenProgram = this.getTokenProgramForSpotMarket(outMarket);
4278
4287
 
4279
4288
  preInstructions.push(
4280
4289
  this.createAssociatedTokenAccountIdempotentInstruction(
@@ -4497,8 +4506,8 @@ export class DriftClient {
4497
4506
  const outSpotMarket = this.getSpotMarketAccount(outMarketIndex);
4498
4507
  const inSpotMarket = this.getSpotMarketAccount(inMarketIndex);
4499
4508
 
4500
- const outTokenProgram = getTokenProgramForSpotMarket(outSpotMarket);
4501
- const inTokenProgram = getTokenProgramForSpotMarket(inSpotMarket);
4509
+ const outTokenProgram = this.getTokenProgramForSpotMarket(outSpotMarket);
4510
+ const inTokenProgram = this.getTokenProgramForSpotMarket(inSpotMarket);
4502
4511
 
4503
4512
  if (!outTokenProgram.equals(inTokenProgram)) {
4504
4513
  remainingAccounts.push({
@@ -5990,6 +5999,81 @@ export class DriftClient {
5990
5999
  );
5991
6000
  }
5992
6001
 
6002
+ public async liquidatePerpWithFill(
6003
+ userAccountPublicKey: PublicKey,
6004
+ userAccount: UserAccount,
6005
+ marketIndex: number,
6006
+ makerInfos: MakerInfo[],
6007
+ txParams?: TxParams,
6008
+ liquidatorSubAccountId?: number
6009
+ ): Promise<TransactionSignature> {
6010
+ const { txSig, slot } = await this.sendTransaction(
6011
+ await this.buildTransaction(
6012
+ await this.getLiquidatePerpWithFillIx(
6013
+ userAccountPublicKey,
6014
+ userAccount,
6015
+ marketIndex,
6016
+ makerInfos,
6017
+ liquidatorSubAccountId
6018
+ ),
6019
+ txParams
6020
+ ),
6021
+ [],
6022
+ this.opts
6023
+ );
6024
+ this.perpMarketLastSlotCache.set(marketIndex, slot);
6025
+ return txSig;
6026
+ }
6027
+
6028
+ public async getLiquidatePerpWithFillIx(
6029
+ userAccountPublicKey: PublicKey,
6030
+ userAccount: UserAccount,
6031
+ marketIndex: number,
6032
+ makerInfos: MakerInfo[],
6033
+ liquidatorSubAccountId?: number
6034
+ ): Promise<TransactionInstruction> {
6035
+ const userStatsPublicKey = getUserStatsAccountPublicKey(
6036
+ this.program.programId,
6037
+ userAccount.authority
6038
+ );
6039
+
6040
+ const liquidator = await this.getUserAccountPublicKey(
6041
+ liquidatorSubAccountId
6042
+ );
6043
+ const liquidatorStatsPublicKey = this.getUserStatsAccountPublicKey();
6044
+
6045
+ const remainingAccounts = this.getRemainingAccounts({
6046
+ userAccounts: [this.getUserAccount(liquidatorSubAccountId), userAccount],
6047
+ useMarketLastSlotCache: true,
6048
+ writablePerpMarketIndexes: [marketIndex],
6049
+ });
6050
+
6051
+ for (const makerInfo of makerInfos) {
6052
+ remainingAccounts.push({
6053
+ pubkey: makerInfo.maker,
6054
+ isSigner: false,
6055
+ isWritable: true,
6056
+ });
6057
+ remainingAccounts.push({
6058
+ pubkey: makerInfo.makerStats,
6059
+ isSigner: false,
6060
+ isWritable: true,
6061
+ });
6062
+ }
6063
+
6064
+ return await this.program.instruction.liquidatePerpWithFill(marketIndex, {
6065
+ accounts: {
6066
+ state: await this.getStatePublicKey(),
6067
+ authority: this.wallet.publicKey,
6068
+ user: userAccountPublicKey,
6069
+ userStats: userStatsPublicKey,
6070
+ liquidator,
6071
+ liquidatorStats: liquidatorStatsPublicKey,
6072
+ },
6073
+ remainingAccounts: remainingAccounts,
6074
+ });
6075
+ }
6076
+
5993
6077
  public async liquidateSpot(
5994
6078
  userAccountPublicKey: PublicKey,
5995
6079
  userAccount: UserAccount,
@@ -6576,7 +6660,7 @@ export class DriftClient {
6576
6660
 
6577
6661
  const remainingAccounts = [];
6578
6662
  this.addTokenMintToRemainingAccounts(spotMarket, remainingAccounts);
6579
- const tokenProgram = getTokenProgramForSpotMarket(spotMarket);
6663
+ const tokenProgram = this.getTokenProgramForSpotMarket(spotMarket);
6580
6664
  const ix = this.program.instruction.addInsuranceFundStake(
6581
6665
  marketIndex,
6582
6666
  amount,
@@ -6816,7 +6900,7 @@ export class DriftClient {
6816
6900
 
6817
6901
  const remainingAccounts = [];
6818
6902
  this.addTokenMintToRemainingAccounts(spotMarketAccount, remainingAccounts);
6819
- const tokenProgram = getTokenProgramForSpotMarket(spotMarketAccount);
6903
+ const tokenProgram = this.getTokenProgramForSpotMarket(spotMarketAccount);
6820
6904
  const removeStakeIx =
6821
6905
  await this.program.instruction.removeInsuranceFundStake(marketIndex, {
6822
6906
  accounts: {
@@ -6947,7 +7031,7 @@ export class DriftClient {
6947
7031
 
6948
7032
  const remainingAccounts = [];
6949
7033
  this.addTokenMintToRemainingAccounts(spotMarket, remainingAccounts);
6950
- const tokenProgram = getTokenProgramForSpotMarket(spotMarket);
7034
+ const tokenProgram = this.getTokenProgramForSpotMarket(spotMarket);
6951
7035
  const ix = await this.program.instruction.depositIntoSpotMarketRevenuePool(
6952
7036
  amount,
6953
7037
  {
@@ -1675,6 +1675,47 @@
1675
1675
  }
1676
1676
  ]
1677
1677
  },
1678
+ {
1679
+ "name": "liquidatePerpWithFill",
1680
+ "accounts": [
1681
+ {
1682
+ "name": "state",
1683
+ "isMut": false,
1684
+ "isSigner": false
1685
+ },
1686
+ {
1687
+ "name": "authority",
1688
+ "isMut": false,
1689
+ "isSigner": true
1690
+ },
1691
+ {
1692
+ "name": "liquidator",
1693
+ "isMut": true,
1694
+ "isSigner": false
1695
+ },
1696
+ {
1697
+ "name": "liquidatorStats",
1698
+ "isMut": true,
1699
+ "isSigner": false
1700
+ },
1701
+ {
1702
+ "name": "user",
1703
+ "isMut": true,
1704
+ "isSigner": false
1705
+ },
1706
+ {
1707
+ "name": "userStats",
1708
+ "isMut": true,
1709
+ "isSigner": false
1710
+ }
1711
+ ],
1712
+ "args": [
1713
+ {
1714
+ "name": "marketIndex",
1715
+ "type": "u16"
1716
+ }
1717
+ ]
1718
+ },
1678
1719
  {
1679
1720
  "name": "liquidateSpot",
1680
1721
  "accounts": [
@@ -3362,27 +3403,6 @@
3362
3403
  }
3363
3404
  ]
3364
3405
  },
3365
- {
3366
- "name": "initializePredictionMarket",
3367
- "accounts": [
3368
- {
3369
- "name": "admin",
3370
- "isMut": false,
3371
- "isSigner": true
3372
- },
3373
- {
3374
- "name": "state",
3375
- "isMut": false,
3376
- "isSigner": false
3377
- },
3378
- {
3379
- "name": "perpMarket",
3380
- "isMut": true,
3381
- "isSigner": false
3382
- }
3383
- ],
3384
- "args": []
3385
- },
3386
3406
  {
3387
3407
  "name": "deleteInitializedPerpMarket",
3388
3408
  "accounts": [
@@ -9858,6 +9878,9 @@
9858
9878
  },
9859
9879
  {
9860
9880
  "name": "PlaceAndTake"
9881
+ },
9882
+ {
9883
+ "name": "Liquidation"
9861
9884
  }
9862
9885
  ]
9863
9886
  }
@@ -10125,9 +10148,6 @@
10125
10148
  },
10126
10149
  {
10127
10150
  "name": "Future"
10128
- },
10129
- {
10130
- "name": "Prediction"
10131
10151
  }
10132
10152
  ]
10133
10153
  }
@@ -12797,9 +12817,14 @@
12797
12817
  "code": 6282,
12798
12818
  "name": "NonZeroTransferFee",
12799
12819
  "msg": "Non zero transfer fee"
12820
+ },
12821
+ {
12822
+ "code": 6283,
12823
+ "name": "LiquidationOrderFailedToFill",
12824
+ "msg": "Liquidation order failed to fill"
12800
12825
  }
12801
12826
  ],
12802
12827
  "metadata": {
12803
12828
  "address": "dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH"
12804
12829
  }
12805
- }
12830
+ }
@@ -95,9 +95,8 @@ export class OpenbookV2Subscriber implements L2OrderBookGenerator {
95
95
  this.subscribed = true;
96
96
  }
97
97
 
98
- public async getBestBid(): Promise<BN | undefined> {
99
- const bids = await this.market.loadBids();
100
- const bestBid = bids.best();
98
+ public getBestBid(): BN | undefined {
99
+ const bestBid = this.market.bids.best();
101
100
 
102
101
  if (bestBid === undefined) {
103
102
  return undefined;
@@ -106,9 +105,8 @@ export class OpenbookV2Subscriber implements L2OrderBookGenerator {
106
105
  return new BN(Math.floor(bestBid.price * PRICE_PRECISION.toNumber()));
107
106
  }
108
107
 
109
- public async getBestAsk(): Promise<BN | undefined> {
110
- const asks = await this.market.loadAsks();
111
- const bestAsk = asks.best();
108
+ public getBestAsk(): BN | undefined {
109
+ const bestAsk = this.market.asks.best();
112
110
 
113
111
  if (bestAsk === undefined) {
114
112
  return undefined;