@drift-labs/sdk 2.23.0-beta.1 → 2.24.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.
@@ -7,7 +7,8 @@ export declare class AdminClient extends DriftClient {
7
7
  initialize(usdcMint: PublicKey, _adminControlsPrices: boolean): Promise<[TransactionSignature]>;
8
8
  initializeSpotMarket(mint: PublicKey, optimalUtilization: number, optimalRate: number, maxRate: number, oracle: PublicKey, oracleSource: OracleSource, initialAssetWeight: number, maintenanceAssetWeight: number, initialLiabilityWeight: number, maintenanceLiabilityWeight: number, imfFactor?: number, liquidatorFee?: number, activeStatus?: boolean, name?: string): Promise<TransactionSignature>;
9
9
  initializeSerumFulfillmentConfig(marketIndex: number, serumMarket: PublicKey, serumProgram: PublicKey): Promise<TransactionSignature>;
10
- initializePerpMarket(priceOracle: PublicKey, baseAssetReserve: BN, quoteAssetReserve: BN, periodicity: BN, pegMultiplier?: BN, oracleSource?: OracleSource, marginRatioInitial?: number, marginRatioMaintenance?: number, liquidatorFee?: number, activeStatus?: boolean, name?: string): Promise<TransactionSignature>;
10
+ initializePerpMarket(marketIndex: number, priceOracle: PublicKey, baseAssetReserve: BN, quoteAssetReserve: BN, periodicity: BN, pegMultiplier?: BN, oracleSource?: OracleSource, marginRatioInitial?: number, marginRatioMaintenance?: number, liquidatorFee?: number, activeStatus?: boolean, name?: string): Promise<TransactionSignature>;
11
+ deleteInitializedPerpMarket(marketIndex: number): Promise<TransactionSignature>;
11
12
  moveAmmPrice(perpMarketIndex: number, baseAssetReserve: BN, quoteAssetReserve: BN, sqrtK?: BN): Promise<TransactionSignature>;
12
13
  updateK(perpMarketIndex: number, sqrtK: BN): Promise<TransactionSignature>;
13
14
  updatePerpMarketConcentrationScale(perpMarketIndex: number, concentrationScale: BN): Promise<TransactionSignature>;
@@ -107,11 +107,11 @@ class AdminClient extends driftClient_1.DriftClient {
107
107
  const { txSig } = await this.sendTransaction(tx, [], this.opts);
108
108
  return txSig;
109
109
  }
110
- async initializePerpMarket(priceOracle, baseAssetReserve, quoteAssetReserve, periodicity, pegMultiplier = numericConstants_1.PEG_PRECISION, oracleSource = types_1.OracleSource.PYTH, marginRatioInitial = 2000, marginRatioMaintenance = 500, liquidatorFee = 0, activeStatus = true, name = userName_1.DEFAULT_MARKET_NAME) {
110
+ async initializePerpMarket(marketIndex, priceOracle, baseAssetReserve, quoteAssetReserve, periodicity, pegMultiplier = numericConstants_1.PEG_PRECISION, oracleSource = types_1.OracleSource.PYTH, marginRatioInitial = 2000, marginRatioMaintenance = 500, liquidatorFee = 0, activeStatus = true, name = userName_1.DEFAULT_MARKET_NAME) {
111
111
  const currentPerpMarketIndex = this.getStateAccount().numberOfMarkets;
112
112
  const perpMarketPublicKey = await (0, pda_1.getPerpMarketPublicKey)(this.program.programId, currentPerpMarketIndex);
113
113
  const nameBuffer = (0, userName_1.encodeName)(name);
114
- const initializeMarketTx = await this.program.transaction.initializePerpMarket(baseAssetReserve, quoteAssetReserve, periodicity, pegMultiplier, oracleSource, marginRatioInitial, marginRatioMaintenance, liquidatorFee, activeStatus, nameBuffer, {
114
+ const initializeMarketTx = await this.program.transaction.initializePerpMarket(marketIndex, baseAssetReserve, quoteAssetReserve, periodicity, pegMultiplier, oracleSource, marginRatioInitial, marginRatioMaintenance, liquidatorFee, activeStatus, nameBuffer, {
115
115
  accounts: {
116
116
  state: await this.getStatePublicKey(),
117
117
  admin: this.wallet.publicKey,
@@ -132,6 +132,18 @@ class AdminClient extends driftClient_1.DriftClient {
132
132
  });
133
133
  return txSig;
134
134
  }
135
+ async deleteInitializedPerpMarket(marketIndex) {
136
+ const perpMarketPublicKey = await (0, pda_1.getPerpMarketPublicKey)(this.program.programId, marketIndex);
137
+ const deleteInitializeMarketTx = await this.program.transaction.deleteInitializedPerpMarket(marketIndex, {
138
+ accounts: {
139
+ state: await this.getStatePublicKey(),
140
+ admin: this.wallet.publicKey,
141
+ perpMarket: perpMarketPublicKey,
142
+ },
143
+ });
144
+ const { txSig } = await this.sendTransaction(deleteInitializeMarketTx, [], this.opts);
145
+ return txSig;
146
+ }
135
147
  async moveAmmPrice(perpMarketIndex, baseAssetReserve, quoteAssetReserve, sqrtK) {
136
148
  const marketPublicKey = await (0, pda_1.getPerpMarketPublicKey)(this.program.programId, perpMarketIndex);
137
149
  if (sqrtK == undefined) {
@@ -46,7 +46,7 @@ exports.DevnetPerpMarkets = [
46
46
  },
47
47
  {
48
48
  fullName: 'Bonk',
49
- category: ['Meme'],
49
+ category: ['Meme', 'Dog'],
50
50
  symbol: '1MBONK-PERP',
51
51
  baseAssetSymbol: '1MBONK',
52
52
  marketIndex: 4,
@@ -74,6 +74,16 @@ exports.DevnetPerpMarkets = [
74
74
  launchTs: 1679501812000,
75
75
  oracleSource: __1.OracleSource.PYTH,
76
76
  },
77
+ {
78
+ fullName: 'Doge',
79
+ category: ['Meme', 'Dog'],
80
+ symbol: 'DOGE-PERP',
81
+ baseAssetSymbol: 'DOGE',
82
+ marketIndex: 7,
83
+ oracle: new web3_js_1.PublicKey('4L6YhY8VvUgmqG5MvJkUJATtzB2rFqdrJwQCmFLv4Jzy'),
84
+ launchTs: 1680808053000,
85
+ oracleSource: __1.OracleSource.PYTH,
86
+ },
77
87
  ];
78
88
  exports.MainnetPerpMarkets = [
79
89
  {
@@ -146,6 +156,16 @@ exports.MainnetPerpMarkets = [
146
156
  launchTs: 1679501812000,
147
157
  oracleSource: __1.OracleSource.PYTH,
148
158
  },
159
+ {
160
+ fullName: 'Doge',
161
+ category: ['Meme', 'Dog'],
162
+ symbol: 'DOGE-PERP',
163
+ baseAssetSymbol: 'DOGE',
164
+ marketIndex: 7,
165
+ oracle: new web3_js_1.PublicKey('FsSM3s38PX9K7Dn6eGzuE29S2Dsk1Sss1baytTQdCaQj'),
166
+ launchTs: 1680808053000,
167
+ oracleSource: __1.OracleSource.PYTH,
168
+ },
149
169
  ];
150
170
  exports.PerpMarkets = {
151
171
  devnet: exports.DevnetPerpMarkets,
@@ -93,6 +93,7 @@ export declare class DriftClient {
93
93
  updateWallet(newWallet: IWallet, subAccountIds?: number[], activeSubAccountId?: number): Promise<void>;
94
94
  switchActiveUser(subAccountId: number): void;
95
95
  addUser(subAccountId: number): Promise<void>;
96
+ addAllUsers(): Promise<void>;
96
97
  initializeUserAccount(subAccountId?: number, name?: string, referrerInfo?: ReferrerInfo): Promise<[TransactionSignature, PublicKey]>;
97
98
  getInitializeUserInstructions(subAccountId?: number, name?: string, referrerInfo?: ReferrerInfo): Promise<[PublicKey, TransactionInstruction]>;
98
99
  getInitializeUserStatsIx(): Promise<TransactionInstruction>;
@@ -103,6 +104,7 @@ export declare class DriftClient {
103
104
  updateUserDelegate(delegate: PublicKey, subAccountId?: number): Promise<TransactionSignature>;
104
105
  fetchAllUserAccounts(includeIdle?: boolean): Promise<ProgramAccount<UserAccount>[]>;
105
106
  getUserAccountsForDelegate(delegate: PublicKey): Promise<UserAccount[]>;
107
+ getUserAccountsAndAddressesForAuthority(authority: PublicKey): Promise<ProgramAccount<UserAccount>[]>;
106
108
  getUserAccountsForAuthority(authority: PublicKey): Promise<UserAccount[]>;
107
109
  getReferredUserStatsAccountsByReferrer(referrer: PublicKey): Promise<UserStatsAccount[]>;
108
110
  getReferrerNameAccountsForAuthority(authority: PublicKey): Promise<ReferrerNameAccount[]>;
@@ -323,7 +325,25 @@ export declare class DriftClient {
323
325
  getOracleDataForSpotMarket(marketIndex: number): OraclePriceData;
324
326
  initializeInsuranceFundStake(marketIndex: number, txParams?: TxParams): Promise<TransactionSignature>;
325
327
  getInitializeInsuranceFundStakeIx(marketIndex: number): Promise<TransactionInstruction>;
326
- addInsuranceFundStake(marketIndex: number, amount: BN, collateralAccountPublicKey: PublicKey): Promise<TransactionSignature>;
328
+ getAddInsuranceFundStakeIx(marketIndex: number, amount: BN, collateralAccountPublicKey: PublicKey): Promise<TransactionInstruction>;
329
+ /**
330
+ * Add to an insurance fund stake and optionally initialize the account
331
+ */
332
+ addInsuranceFundStake({ marketIndex, amount, collateralAccountPublicKey, initializeStakeAccount, }: {
333
+ /**
334
+ * Spot market index
335
+ */
336
+ marketIndex: number;
337
+ amount: BN;
338
+ /**
339
+ * The account where the funds to stake come from. Usually an associated token account
340
+ */
341
+ collateralAccountPublicKey: PublicKey;
342
+ /**
343
+ * Add instructions to initialize the staking account -- required if its the first time the currrent authority has staked in this market
344
+ */
345
+ initializeStakeAccount?: boolean;
346
+ }): Promise<TransactionSignature>;
327
347
  requestRemoveInsuranceFundStake(marketIndex: number, amount: BN): Promise<TransactionSignature>;
328
348
  cancelRequestRemoveInsuranceFundStake(marketIndex: number): Promise<TransactionSignature>;
329
349
  removeInsuranceFundStake(marketIndex: number, collateralAccountPublicKey: PublicKey): Promise<TransactionSignature>;
@@ -246,7 +246,6 @@ class DriftClient {
246
246
  if (!this.marketLookupTable) {
247
247
  throw Error('Market lookup table address not set');
248
248
  }
249
- // @ts-ignore
250
249
  return (await this.connection.getAddressLookupTable(this.marketLookupTable))
251
250
  .value;
252
251
  }
@@ -298,6 +297,12 @@ class DriftClient {
298
297
  await user.subscribe();
299
298
  this.users.set(subAccountId, user);
300
299
  }
300
+ async addAllUsers() {
301
+ const userAccounts = await this.getUserAccountsForAuthority(this.authority);
302
+ for (const userAccount of userAccounts) {
303
+ await this.addUser(userAccount.subAccountId);
304
+ }
305
+ }
301
306
  async initializeUserAccount(subAccountId = 0, name = userName_1.DEFAULT_USER_NAME, referrerInfo) {
302
307
  const [userAccountPublicKey, initializeUserAccountIx] = await this.getInitializeUserInstructions(subAccountId, name, referrerInfo);
303
308
  const tx = new web3_js_1.Transaction();
@@ -453,6 +458,18 @@ class DriftClient {
453
458
  ]);
454
459
  return programAccounts.map((programAccount) => programAccount.account);
455
460
  }
461
+ async getUserAccountsAndAddressesForAuthority(authority) {
462
+ const programAccounts = await this.program.account.user.all([
463
+ {
464
+ memcmp: {
465
+ offset: 8,
466
+ /** data to match, as base-58 encoded string and limited to less than 129 bytes */
467
+ bytes: bs58_1.default.encode(authority.toBuffer()),
468
+ },
469
+ },
470
+ ]);
471
+ return programAccounts.map((programAccount) => programAccount);
472
+ }
456
473
  async getUserAccountsForAuthority(authority) {
457
474
  const programAccounts = await this.program.account.user.all([
458
475
  {
@@ -801,9 +818,7 @@ class DriftClient {
801
818
  }
802
819
  async deposit(amount, marketIndex, collateralAccountPublicKey, subAccountId, reduceOnly = false) {
803
820
  const tx = new web3_js_1.Transaction();
804
- tx.add(
805
- // @ts-ignore
806
- web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
821
+ tx.add(web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
807
822
  units: 600000,
808
823
  }));
809
824
  const additionalSigners = [];
@@ -916,15 +931,11 @@ class DriftClient {
916
931
  const spotMarket = this.getSpotMarketAccount(marketIndex);
917
932
  const isSolMarket = spotMarket.mint.equals(spotMarkets_1.WRAPPED_SOL_MINT);
918
933
  const tx = new web3_js_1.Transaction();
919
- tx.add(
920
- // @ts-ignore
921
- web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
934
+ tx.add(web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
922
935
  units: (_a = txParams === null || txParams === void 0 ? void 0 : txParams.computeUnits) !== null && _a !== void 0 ? _a : 600000,
923
936
  }));
924
937
  if (txParams === null || txParams === void 0 ? void 0 : txParams.computeUnitsPrice) {
925
- tx.add(
926
- // @ts-ignore
927
- web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({
938
+ tx.add(web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({
928
939
  microLamports: txParams.computeUnitsPrice,
929
940
  }));
930
941
  }
@@ -971,9 +982,7 @@ class DriftClient {
971
982
  }
972
983
  async withdraw(amount, marketIndex, userTokenAccount, reduceOnly = false) {
973
984
  const tx = new web3_js_1.Transaction();
974
- tx.add(
975
- // @ts-ignore
976
- web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
985
+ tx.add(web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
977
986
  units: 600000,
978
987
  }));
979
988
  const additionalSigners = [];
@@ -2048,9 +2057,7 @@ class DriftClient {
2048
2057
  ? await this.getPlaceSpotOrderIx(newOrderParams)
2049
2058
  : await this.getPlacePerpOrderIx(newOrderParams);
2050
2059
  const tx = new web3_js_1.Transaction();
2051
- tx.add(
2052
- // @ts-ignore
2053
- web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
2060
+ tx.add(web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
2054
2061
  units: 1000000,
2055
2062
  }));
2056
2063
  tx.add(cancelOrderIx);
@@ -2125,9 +2132,7 @@ class DriftClient {
2125
2132
  ? await this.getPlaceSpotOrderIx(newOrderParams)
2126
2133
  : await this.getPlacePerpOrderIx(newOrderParams);
2127
2134
  const tx = new web3_js_1.Transaction();
2128
- tx.add(
2129
- // @ts-ignore
2130
- web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
2135
+ tx.add(web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
2131
2136
  units: 1000000,
2132
2137
  }));
2133
2138
  tx.add(cancelOrderIx);
@@ -2150,9 +2155,7 @@ class DriftClient {
2150
2155
  }
2151
2156
  }
2152
2157
  const tx = new web3_js_1.Transaction()
2153
- .add(
2154
- // @ts-ignore
2155
- web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
2158
+ .add(web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
2156
2159
  units: 1000000,
2157
2160
  }))
2158
2161
  .add(...ixs);
@@ -2415,7 +2418,7 @@ class DriftClient {
2415
2418
  },
2416
2419
  });
2417
2420
  }
2418
- async addInsuranceFundStake(marketIndex, amount, collateralAccountPublicKey) {
2421
+ async getAddInsuranceFundStakeIx(marketIndex, amount, collateralAccountPublicKey) {
2419
2422
  const spotMarket = this.getSpotMarketAccount(marketIndex);
2420
2423
  const ifStakeAccountPublicKey = (0, pda_1.getInsuranceFundStakeAccountPublicKey)(this.program.programId, this.wallet.publicKey, marketIndex);
2421
2424
  const remainingAccounts = this.getRemainingAccounts({
@@ -2423,7 +2426,7 @@ class DriftClient {
2423
2426
  useMarketLastSlotCache: true,
2424
2427
  writableSpotMarketIndexes: [marketIndex],
2425
2428
  });
2426
- const tx = await this.program.transaction.addInsuranceFundStake(marketIndex, amount, {
2429
+ const ix = this.program.instruction.addInsuranceFundStake(marketIndex, amount, {
2427
2430
  accounts: {
2428
2431
  state: await this.getStatePublicKey(),
2429
2432
  spotMarket: spotMarket.pubkey,
@@ -2438,7 +2441,39 @@ class DriftClient {
2438
2441
  },
2439
2442
  remainingAccounts,
2440
2443
  });
2441
- const { txSig } = await this.sendTransaction(tx, [], this.opts);
2444
+ return ix;
2445
+ }
2446
+ /**
2447
+ * Add to an insurance fund stake and optionally initialize the account
2448
+ */
2449
+ async addInsuranceFundStake({ marketIndex, amount, collateralAccountPublicKey, initializeStakeAccount, }) {
2450
+ const tx = new web3_js_1.Transaction();
2451
+ const additionalSigners = [];
2452
+ const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
2453
+ const isSolMarket = spotMarketAccount.mint.equals(spotMarkets_1.WRAPPED_SOL_MINT);
2454
+ const createWSOLTokenAccount = isSolMarket && collateralAccountPublicKey.equals(this.wallet.publicKey);
2455
+ let tokenAccount;
2456
+ if (createWSOLTokenAccount) {
2457
+ const { ixs, signers, pubkey } = await this.getWrappedSolAccountCreationIxs(amount, true);
2458
+ tokenAccount = pubkey;
2459
+ ixs.forEach((ix) => {
2460
+ tx.add(ix);
2461
+ });
2462
+ signers.forEach((signer) => additionalSigners.push(signer));
2463
+ }
2464
+ else {
2465
+ tokenAccount = collateralAccountPublicKey;
2466
+ }
2467
+ if (initializeStakeAccount) {
2468
+ const initializeIx = await this.getInitializeInsuranceFundStakeIx(marketIndex);
2469
+ tx.add(initializeIx);
2470
+ }
2471
+ const addFundsIx = await this.getAddInsuranceFundStakeIx(marketIndex, amount, tokenAccount);
2472
+ tx.add(addFundsIx);
2473
+ if (createWSOLTokenAccount) {
2474
+ tx.add(spl_token_1.Token.createCloseAccountInstruction(spl_token_1.TOKEN_PROGRAM_ID, tokenAccount, this.wallet.publicKey, this.wallet.publicKey, []));
2475
+ }
2476
+ const { txSig } = await this.sendTransaction(tx, additionalSigners, this.opts);
2442
2477
  return txSig;
2443
2478
  }
2444
2479
  async requestRemoveInsuranceFundStake(marketIndex, amount) {
@@ -2486,14 +2521,31 @@ class DriftClient {
2486
2521
  return txSig;
2487
2522
  }
2488
2523
  async removeInsuranceFundStake(marketIndex, collateralAccountPublicKey) {
2524
+ const tx = new web3_js_1.Transaction();
2489
2525
  const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
2490
2526
  const ifStakeAccountPublicKey = (0, pda_1.getInsuranceFundStakeAccountPublicKey)(this.program.programId, this.wallet.publicKey, marketIndex);
2527
+ const tokenAccount = collateralAccountPublicKey;
2528
+ // Todo wsol remove iF stake... how do we determine the amount?
2529
+ // const amount = // get balance here...?
2530
+ // const additionalSigners: Array<Signer> = [];
2531
+ // const isSolMarket = spotMarketAccount.mint.equals(WRAPPED_SOL_MINT);
2532
+ // const createWSOLTokenAccount =
2533
+ // isSolMarket && collateralAccountPublicKey.equals(this.wallet.publicKey);
2534
+ // if (createWSOLTokenAccount) {
2535
+ // const { ixs, signers, pubkey } =
2536
+ // await this.getWrappedSolAccountCreationIxs(amount, true);
2537
+ // tokenAccount = pubkey;
2538
+ // ixs.forEach((ix) => {
2539
+ // tx.add(ix);
2540
+ // });
2541
+ // signers.forEach((signer) => additionalSigners.push(signer));
2542
+ // }
2491
2543
  const remainingAccounts = this.getRemainingAccounts({
2492
2544
  userAccounts: [this.getUserAccount()],
2493
2545
  useMarketLastSlotCache: true,
2494
2546
  writableSpotMarketIndexes: [marketIndex],
2495
2547
  });
2496
- const tx = await this.program.transaction.removeInsuranceFundStake(marketIndex, {
2548
+ const removeStakeIx = await this.program.instruction.removeInsuranceFundStake(marketIndex, {
2497
2549
  accounts: {
2498
2550
  state: await this.getStatePublicKey(),
2499
2551
  spotMarket: spotMarketAccount.pubkey,
@@ -2502,11 +2554,12 @@ class DriftClient {
2502
2554
  authority: this.wallet.publicKey,
2503
2555
  insuranceFundVault: spotMarketAccount.insuranceFund.vault,
2504
2556
  driftSigner: this.getSignerPublicKey(),
2505
- userTokenAccount: collateralAccountPublicKey,
2557
+ userTokenAccount: tokenAccount,
2506
2558
  tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
2507
2559
  },
2508
2560
  remainingAccounts,
2509
2561
  });
2562
+ tx.add(removeStakeIx);
2510
2563
  const { txSig } = await this.sendTransaction(tx, [], this.opts);
2511
2564
  return txSig;
2512
2565
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.23.0-beta.1",
2
+ "version": "2.24.0",
3
3
  "name": "drift",
4
4
  "instructions": [
5
5
  {
@@ -2283,6 +2283,10 @@
2283
2283
  }
2284
2284
  ],
2285
2285
  "args": [
2286
+ {
2287
+ "name": "marketIndex",
2288
+ "type": "u16"
2289
+ },
2286
2290
  {
2287
2291
  "name": "ammBaseAssetReserve",
2288
2292
  "type": "u128"
@@ -2332,6 +2336,32 @@
2332
2336
  }
2333
2337
  ]
2334
2338
  },
2339
+ {
2340
+ "name": "deleteInitializedPerpMarket",
2341
+ "accounts": [
2342
+ {
2343
+ "name": "admin",
2344
+ "isMut": true,
2345
+ "isSigner": true
2346
+ },
2347
+ {
2348
+ "name": "state",
2349
+ "isMut": true,
2350
+ "isSigner": false
2351
+ },
2352
+ {
2353
+ "name": "perpMarket",
2354
+ "isMut": true,
2355
+ "isSigner": false
2356
+ }
2357
+ ],
2358
+ "args": [
2359
+ {
2360
+ "name": "marketIndex",
2361
+ "type": "u16"
2362
+ }
2363
+ ]
2364
+ },
2335
2365
  {
2336
2366
  "name": "moveAmmPrice",
2337
2367
  "accounts": [
@@ -5994,6 +6024,22 @@
5994
6024
  ]
5995
6025
  }
5996
6026
  },
6027
+ {
6028
+ "name": "FulfillmentParams",
6029
+ "type": {
6030
+ "kind": "enum",
6031
+ "variants": [
6032
+ {
6033
+ "name": "SerumFulfillmentParams",
6034
+ "fields": [
6035
+ {
6036
+ "defined": "SerumFulfillmentParams<'a,'b>"
6037
+ }
6038
+ ]
6039
+ }
6040
+ ]
6041
+ }
6042
+ },
5997
6043
  {
5998
6044
  "name": "SpotFulfillmentType",
5999
6045
  "type": {
@@ -8810,6 +8856,11 @@
8810
8856
  "code": 6239,
8811
8857
  "name": "RevertFill",
8812
8858
  "msg": "RevertFill"
8859
+ },
8860
+ {
8861
+ "code": 6240,
8862
+ "name": "InvalidMarketAccountforDeletion",
8863
+ "msg": "Invalid MarketAccount for Deletion"
8813
8864
  }
8814
8865
  ]
8815
8866
  }
package/lib/tx/utils.js CHANGED
@@ -6,16 +6,12 @@ const COMPUTE_UNITS_DEFAULT = 200000;
6
6
  function wrapInTx(instruction, computeUnits = 600000, computeUnitsPrice = 0) {
7
7
  const tx = new web3_js_1.Transaction();
8
8
  if (computeUnits != COMPUTE_UNITS_DEFAULT) {
9
- tx.add(
10
- // @ts-ignore
11
- web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
9
+ tx.add(web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
12
10
  units: computeUnits,
13
11
  }));
14
12
  }
15
13
  if (computeUnitsPrice != 0) {
16
- tx.add(
17
- // @ts-ignore
18
- web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({
14
+ tx.add(web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({
19
15
  microLamports: computeUnitsPrice,
20
16
  }));
21
17
  }
package/lib/types.d.ts CHANGED
@@ -991,6 +991,7 @@ export type OracleGuardRails = {
991
991
  };
992
992
  export type MarginCategory = 'Initial' | 'Maintenance';
993
993
  export type InsuranceFundStake = {
994
+ costBasis: BN;
994
995
  marketIndex: number;
995
996
  authority: PublicKey;
996
997
  ifShares: BN;
package/lib/user.js CHANGED
@@ -1249,7 +1249,8 @@ class User {
1249
1249
  }
1250
1250
  }
1251
1251
  for (const spotPosition of userAccount.spotPositions) {
1252
- if ((0, types_1.isVariant)(spotPosition.balanceType, 'borrow')) {
1252
+ if ((0, types_1.isVariant)(spotPosition.balanceType, 'borrow') &&
1253
+ spotPosition.scaledBalance.gt(numericConstants_1.ZERO)) {
1253
1254
  return false;
1254
1255
  }
1255
1256
  if (spotPosition.openOrders !== 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/sdk",
3
- "version": "2.23.0-beta.1",
3
+ "version": "2.24.0",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "author": "crispheaney",
@@ -182,6 +182,7 @@ export class AdminClient extends DriftClient {
182
182
  }
183
183
 
184
184
  public async initializePerpMarket(
185
+ marketIndex: number,
185
186
  priceOracle: PublicKey,
186
187
  baseAssetReserve: BN,
187
188
  quoteAssetReserve: BN,
@@ -203,6 +204,7 @@ export class AdminClient extends DriftClient {
203
204
  const nameBuffer = encodeName(name);
204
205
  const initializeMarketTx =
205
206
  await this.program.transaction.initializePerpMarket(
207
+ marketIndex,
206
208
  baseAssetReserve,
207
209
  quoteAssetReserve,
208
210
  periodicity,
@@ -243,6 +245,32 @@ export class AdminClient extends DriftClient {
243
245
  return txSig;
244
246
  }
245
247
 
248
+ public async deleteInitializedPerpMarket(
249
+ marketIndex: number
250
+ ): Promise<TransactionSignature> {
251
+ const perpMarketPublicKey = await getPerpMarketPublicKey(
252
+ this.program.programId,
253
+ marketIndex
254
+ );
255
+
256
+ const deleteInitializeMarketTx =
257
+ await this.program.transaction.deleteInitializedPerpMarket(marketIndex, {
258
+ accounts: {
259
+ state: await this.getStatePublicKey(),
260
+ admin: this.wallet.publicKey,
261
+ perpMarket: perpMarketPublicKey,
262
+ },
263
+ });
264
+
265
+ const { txSig } = await this.sendTransaction(
266
+ deleteInitializeMarketTx,
267
+ [],
268
+ this.opts
269
+ );
270
+
271
+ return txSig;
272
+ }
273
+
246
274
  public async moveAmmPrice(
247
275
  perpMarketIndex: number,
248
276
  baseAssetReserve: BN,
@@ -56,7 +56,7 @@ export const DevnetPerpMarkets: PerpMarketConfig[] = [
56
56
  },
57
57
  {
58
58
  fullName: 'Bonk',
59
- category: ['Meme'],
59
+ category: ['Meme', 'Dog'],
60
60
  symbol: '1MBONK-PERP',
61
61
  baseAssetSymbol: '1MBONK',
62
62
  marketIndex: 4,
@@ -84,6 +84,16 @@ export const DevnetPerpMarkets: PerpMarketConfig[] = [
84
84
  launchTs: 1679501812000, //todo
85
85
  oracleSource: OracleSource.PYTH,
86
86
  },
87
+ {
88
+ fullName: 'Doge',
89
+ category: ['Meme', 'Dog'],
90
+ symbol: 'DOGE-PERP',
91
+ baseAssetSymbol: 'DOGE',
92
+ marketIndex: 7,
93
+ oracle: new PublicKey('4L6YhY8VvUgmqG5MvJkUJATtzB2rFqdrJwQCmFLv4Jzy'),
94
+ launchTs: 1680808053000,
95
+ oracleSource: OracleSource.PYTH,
96
+ },
87
97
  ];
88
98
 
89
99
  export const MainnetPerpMarkets: PerpMarketConfig[] = [
@@ -157,6 +167,16 @@ export const MainnetPerpMarkets: PerpMarketConfig[] = [
157
167
  launchTs: 1679501812000, //todo
158
168
  oracleSource: OracleSource.PYTH,
159
169
  },
170
+ {
171
+ fullName: 'Doge',
172
+ category: ['Meme', 'Dog'],
173
+ symbol: 'DOGE-PERP',
174
+ baseAssetSymbol: 'DOGE',
175
+ marketIndex: 7,
176
+ oracle: new PublicKey('FsSM3s38PX9K7Dn6eGzuE29S2Dsk1Sss1baytTQdCaQj'),
177
+ launchTs: 1680808053000,
178
+ oracleSource: OracleSource.PYTH,
179
+ },
160
180
  ];
161
181
 
162
182
  export const PerpMarkets: { [key in DriftEnv]: PerpMarketConfig[] } = {
@@ -418,7 +418,6 @@ export class DriftClient {
418
418
  throw Error('Market lookup table address not set');
419
419
  }
420
420
 
421
- // @ts-ignore
422
421
  return (await this.connection.getAddressLookupTable(this.marketLookupTable))
423
422
  .value;
424
423
  }
@@ -500,6 +499,13 @@ export class DriftClient {
500
499
  this.users.set(subAccountId, user);
501
500
  }
502
501
 
502
+ public async addAllUsers(): Promise<void> {
503
+ const userAccounts = await this.getUserAccountsForAuthority(this.authority);
504
+ for (const userAccount of userAccounts) {
505
+ await this.addUser(userAccount.subAccountId);
506
+ }
507
+ }
508
+
503
509
  public async initializeUserAccount(
504
510
  subAccountId = 0,
505
511
  name = DEFAULT_USER_NAME,
@@ -760,6 +766,24 @@ export class DriftClient {
760
766
  );
761
767
  }
762
768
 
769
+ public async getUserAccountsAndAddressesForAuthority(
770
+ authority: PublicKey
771
+ ): Promise<ProgramAccount<UserAccount>[]> {
772
+ const programAccounts = await this.program.account.user.all([
773
+ {
774
+ memcmp: {
775
+ offset: 8,
776
+ /** data to match, as base-58 encoded string and limited to less than 129 bytes */
777
+ bytes: bs58.encode(authority.toBuffer()),
778
+ },
779
+ },
780
+ ]);
781
+
782
+ return programAccounts.map(
783
+ (programAccount) => programAccount as ProgramAccount<UserAccount>
784
+ );
785
+ }
786
+
763
787
  public async getUserAccountsForAuthority(
764
788
  authority: PublicKey
765
789
  ): Promise<UserAccount[]> {
@@ -1233,7 +1257,6 @@ export class DriftClient {
1233
1257
  ): Promise<TransactionSignature> {
1234
1258
  const tx = new Transaction();
1235
1259
  tx.add(
1236
- // @ts-ignore
1237
1260
  ComputeBudgetProgram.setComputeUnitLimit({
1238
1261
  units: 600_000,
1239
1262
  })
@@ -1459,7 +1482,6 @@ export class DriftClient {
1459
1482
  const tx = new Transaction();
1460
1483
 
1461
1484
  tx.add(
1462
- // @ts-ignore
1463
1485
  ComputeBudgetProgram.setComputeUnitLimit({
1464
1486
  units: txParams?.computeUnits ?? 600_000,
1465
1487
  })
@@ -1467,7 +1489,6 @@ export class DriftClient {
1467
1489
 
1468
1490
  if (txParams?.computeUnitsPrice) {
1469
1491
  tx.add(
1470
- // @ts-ignore
1471
1492
  ComputeBudgetProgram.setComputeUnitPrice({
1472
1493
  microLamports: txParams.computeUnitsPrice,
1473
1494
  })
@@ -1598,7 +1619,6 @@ export class DriftClient {
1598
1619
  ): Promise<TransactionSignature> {
1599
1620
  const tx = new Transaction();
1600
1621
  tx.add(
1601
- // @ts-ignore
1602
1622
  ComputeBudgetProgram.setComputeUnitLimit({
1603
1623
  units: 600_000,
1604
1624
  })
@@ -3458,7 +3478,6 @@ export class DriftClient {
3458
3478
 
3459
3479
  const tx = new Transaction();
3460
3480
  tx.add(
3461
- // @ts-ignore
3462
3481
  ComputeBudgetProgram.setComputeUnitLimit({
3463
3482
  units: 1_000_000,
3464
3483
  })
@@ -3570,7 +3589,6 @@ export class DriftClient {
3570
3589
 
3571
3590
  const tx = new Transaction();
3572
3591
  tx.add(
3573
- // @ts-ignore
3574
3592
  ComputeBudgetProgram.setComputeUnitLimit({
3575
3593
  units: 1_000_000,
3576
3594
  })
@@ -3611,7 +3629,6 @@ export class DriftClient {
3611
3629
 
3612
3630
  const tx = new Transaction()
3613
3631
  .add(
3614
- // @ts-ignore
3615
3632
  ComputeBudgetProgram.setComputeUnitLimit({
3616
3633
  units: 1_000_000,
3617
3634
  })
@@ -4206,11 +4223,11 @@ export class DriftClient {
4206
4223
  );
4207
4224
  }
4208
4225
 
4209
- public async addInsuranceFundStake(
4226
+ public async getAddInsuranceFundStakeIx(
4210
4227
  marketIndex: number,
4211
4228
  amount: BN,
4212
4229
  collateralAccountPublicKey: PublicKey
4213
- ): Promise<TransactionSignature> {
4230
+ ): Promise<TransactionInstruction> {
4214
4231
  const spotMarket = this.getSpotMarketAccount(marketIndex);
4215
4232
  const ifStakeAccountPublicKey = getInsuranceFundStakeAccountPublicKey(
4216
4233
  this.program.programId,
@@ -4224,7 +4241,7 @@ export class DriftClient {
4224
4241
  writableSpotMarketIndexes: [marketIndex],
4225
4242
  });
4226
4243
 
4227
- const tx = await this.program.transaction.addInsuranceFundStake(
4244
+ const ix = this.program.instruction.addInsuranceFundStake(
4228
4245
  marketIndex,
4229
4246
  amount,
4230
4247
  {
@@ -4244,7 +4261,88 @@ export class DriftClient {
4244
4261
  }
4245
4262
  );
4246
4263
 
4247
- const { txSig } = await this.sendTransaction(tx, [], this.opts);
4264
+ return ix;
4265
+ }
4266
+
4267
+ /**
4268
+ * Add to an insurance fund stake and optionally initialize the account
4269
+ */
4270
+ public async addInsuranceFundStake({
4271
+ marketIndex,
4272
+ amount,
4273
+ collateralAccountPublicKey,
4274
+ initializeStakeAccount,
4275
+ }: {
4276
+ /**
4277
+ * Spot market index
4278
+ */
4279
+ marketIndex: number;
4280
+ amount: BN;
4281
+ /**
4282
+ * The account where the funds to stake come from. Usually an associated token account
4283
+ */
4284
+ collateralAccountPublicKey: PublicKey;
4285
+ /**
4286
+ * Add instructions to initialize the staking account -- required if its the first time the currrent authority has staked in this market
4287
+ */
4288
+ initializeStakeAccount?: boolean;
4289
+ }): Promise<TransactionSignature> {
4290
+ const tx = new Transaction();
4291
+
4292
+ const additionalSigners: Array<Signer> = [];
4293
+ const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
4294
+ const isSolMarket = spotMarketAccount.mint.equals(WRAPPED_SOL_MINT);
4295
+ const createWSOLTokenAccount =
4296
+ isSolMarket && collateralAccountPublicKey.equals(this.wallet.publicKey);
4297
+
4298
+ let tokenAccount;
4299
+
4300
+ if (createWSOLTokenAccount) {
4301
+ const { ixs, signers, pubkey } =
4302
+ await this.getWrappedSolAccountCreationIxs(amount, true);
4303
+ tokenAccount = pubkey;
4304
+ ixs.forEach((ix) => {
4305
+ tx.add(ix);
4306
+ });
4307
+
4308
+ signers.forEach((signer) => additionalSigners.push(signer));
4309
+ } else {
4310
+ tokenAccount = collateralAccountPublicKey;
4311
+ }
4312
+
4313
+ if (initializeStakeAccount) {
4314
+ const initializeIx = await this.getInitializeInsuranceFundStakeIx(
4315
+ marketIndex
4316
+ );
4317
+ tx.add(initializeIx);
4318
+ }
4319
+
4320
+ const addFundsIx = await this.getAddInsuranceFundStakeIx(
4321
+ marketIndex,
4322
+ amount,
4323
+ tokenAccount
4324
+ );
4325
+
4326
+ tx.add(addFundsIx);
4327
+
4328
+ if (createWSOLTokenAccount) {
4329
+ tx.add(
4330
+ Token.createCloseAccountInstruction(
4331
+ TOKEN_PROGRAM_ID,
4332
+ tokenAccount,
4333
+ this.wallet.publicKey,
4334
+ this.wallet.publicKey,
4335
+ []
4336
+ )
4337
+ );
4338
+ }
4339
+
4340
+ const { txSig } = await this.sendTransaction(
4341
+ tx,
4342
+ additionalSigners,
4343
+ this.opts
4344
+ );
4345
+
4248
4346
  return txSig;
4249
4347
  }
4250
4348
 
@@ -4325,12 +4423,33 @@ export class DriftClient {
4325
4423
  marketIndex: number,
4326
4424
  collateralAccountPublicKey: PublicKey
4327
4425
  ): Promise<TransactionSignature> {
4426
+ const tx = new Transaction();
4328
4427
  const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
4329
4428
  const ifStakeAccountPublicKey = getInsuranceFundStakeAccountPublicKey(
4330
4429
  this.program.programId,
4331
4430
  this.wallet.publicKey,
4332
4431
  marketIndex
4333
4432
  );
4433
+ const tokenAccount = collateralAccountPublicKey;
4434
+
4435
+ // Todo wsol remove iF stake... how do we determine the amount?
4436
+ // const amount = // get balance here...?
4437
+
4438
+ // const additionalSigners: Array<Signer> = [];
4439
+ // const isSolMarket = spotMarketAccount.mint.equals(WRAPPED_SOL_MINT);
4440
+ // const createWSOLTokenAccount =
4441
+ // isSolMarket && collateralAccountPublicKey.equals(this.wallet.publicKey);
4442
+
4443
+ // if (createWSOLTokenAccount) {
4444
+ // const { ixs, signers, pubkey } =
4445
+ // await this.getWrappedSolAccountCreationIxs(amount, true);
4446
+ // tokenAccount = pubkey;
4447
+ // ixs.forEach((ix) => {
4448
+ // tx.add(ix);
4449
+ // });
4450
+
4451
+ // signers.forEach((signer) => additionalSigners.push(signer));
4452
+ // }
4334
4453
 
4335
4454
  const remainingAccounts = this.getRemainingAccounts({
4336
4455
  userAccounts: [this.getUserAccount()],
@@ -4338,9 +4457,8 @@ export class DriftClient {
4338
4457
  writableSpotMarketIndexes: [marketIndex],
4339
4458
  });
4340
4459
 
4341
- const tx = await this.program.transaction.removeInsuranceFundStake(
4342
- marketIndex,
4343
- {
4460
+ const removeStakeIx =
4461
+ await this.program.instruction.removeInsuranceFundStake(marketIndex, {
4344
4462
  accounts: {
4345
4463
  state: await this.getStatePublicKey(),
4346
4464
  spotMarket: spotMarketAccount.pubkey,
@@ -4349,12 +4467,13 @@ export class DriftClient {
4349
4467
  authority: this.wallet.publicKey,
4350
4468
  insuranceFundVault: spotMarketAccount.insuranceFund.vault,
4351
4469
  driftSigner: this.getSignerPublicKey(),
4352
- userTokenAccount: collateralAccountPublicKey,
4470
+ userTokenAccount: tokenAccount,
4353
4471
  tokenProgram: TOKEN_PROGRAM_ID,
4354
4472
  },
4355
4473
  remainingAccounts,
4356
- }
4357
- );
4474
+ });
4475
+
4476
+ tx.add(removeStakeIx);
4358
4477
 
4359
4478
  const { txSig } = await this.sendTransaction(tx, [], this.opts);
4360
4479
  return txSig;
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.23.0-beta.1",
2
+ "version": "2.24.0",
3
3
  "name": "drift",
4
4
  "instructions": [
5
5
  {
@@ -2283,6 +2283,10 @@
2283
2283
  }
2284
2284
  ],
2285
2285
  "args": [
2286
+ {
2287
+ "name": "marketIndex",
2288
+ "type": "u16"
2289
+ },
2286
2290
  {
2287
2291
  "name": "ammBaseAssetReserve",
2288
2292
  "type": "u128"
@@ -2332,6 +2336,32 @@
2332
2336
  }
2333
2337
  ]
2334
2338
  },
2339
+ {
2340
+ "name": "deleteInitializedPerpMarket",
2341
+ "accounts": [
2342
+ {
2343
+ "name": "admin",
2344
+ "isMut": true,
2345
+ "isSigner": true
2346
+ },
2347
+ {
2348
+ "name": "state",
2349
+ "isMut": true,
2350
+ "isSigner": false
2351
+ },
2352
+ {
2353
+ "name": "perpMarket",
2354
+ "isMut": true,
2355
+ "isSigner": false
2356
+ }
2357
+ ],
2358
+ "args": [
2359
+ {
2360
+ "name": "marketIndex",
2361
+ "type": "u16"
2362
+ }
2363
+ ]
2364
+ },
2335
2365
  {
2336
2366
  "name": "moveAmmPrice",
2337
2367
  "accounts": [
@@ -5994,6 +6024,22 @@
5994
6024
  ]
5995
6025
  }
5996
6026
  },
6027
+ {
6028
+ "name": "FulfillmentParams",
6029
+ "type": {
6030
+ "kind": "enum",
6031
+ "variants": [
6032
+ {
6033
+ "name": "SerumFulfillmentParams",
6034
+ "fields": [
6035
+ {
6036
+ "defined": "SerumFulfillmentParams<'a,'b>"
6037
+ }
6038
+ ]
6039
+ }
6040
+ ]
6041
+ }
6042
+ },
5997
6043
  {
5998
6044
  "name": "SpotFulfillmentType",
5999
6045
  "type": {
@@ -8810,6 +8856,11 @@
8810
8856
  "code": 6239,
8811
8857
  "name": "RevertFill",
8812
8858
  "msg": "RevertFill"
8859
+ },
8860
+ {
8861
+ "code": 6240,
8862
+ "name": "InvalidMarketAccountforDeletion",
8863
+ "msg": "Invalid MarketAccount for Deletion"
8813
8864
  }
8814
8865
  ]
8815
8866
  }
package/src/tx/utils.ts CHANGED
@@ -14,7 +14,6 @@ export function wrapInTx(
14
14
  const tx = new Transaction();
15
15
  if (computeUnits != COMPUTE_UNITS_DEFAULT) {
16
16
  tx.add(
17
- // @ts-ignore
18
17
  ComputeBudgetProgram.setComputeUnitLimit({
19
18
  units: computeUnits,
20
19
  })
@@ -23,7 +22,6 @@ export function wrapInTx(
23
22
 
24
23
  if (computeUnitsPrice != 0) {
25
24
  tx.add(
26
- // @ts-ignore
27
25
  ComputeBudgetProgram.setComputeUnitPrice({
28
26
  microLamports: computeUnitsPrice,
29
27
  })
package/src/types.ts CHANGED
@@ -974,6 +974,8 @@ export type OracleGuardRails = {
974
974
  export type MarginCategory = 'Initial' | 'Maintenance';
975
975
 
976
976
  export type InsuranceFundStake = {
977
+ costBasis: BN;
978
+
977
979
  marketIndex: number;
978
980
  authority: PublicKey;
979
981
 
package/src/user.ts CHANGED
@@ -2253,7 +2253,10 @@ export class User {
2253
2253
  }
2254
2254
 
2255
2255
  for (const spotPosition of userAccount.spotPositions) {
2256
- if (isVariant(spotPosition.balanceType, 'borrow')) {
2256
+ if (
2257
+ isVariant(spotPosition.balanceType, 'borrow') &&
2258
+ spotPosition.scaledBalance.gt(ZERO)
2259
+ ) {
2257
2260
  return false;
2258
2261
  }
2259
2262