@drift-labs/sdk-browser 2.155.0-beta.3 → 2.155.0-beta.5
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 +1 -1
- package/lib/browser/decode/user.js +8 -5
- package/lib/browser/driftClient.d.ts +15 -10
- package/lib/browser/driftClient.js +137 -23
- package/lib/browser/marginCalculation.d.ts +0 -12
- package/lib/browser/marginCalculation.js +0 -20
- package/lib/browser/math/margin.js +1 -0
- package/lib/browser/math/position.d.ts +1 -0
- package/lib/browser/math/position.js +10 -2
- package/lib/browser/swap/UnifiedSwapClient.js +1 -10
- package/lib/browser/titan/titanClient.d.ts +4 -5
- package/lib/browser/titan/titanClient.js +2 -16
- package/lib/browser/types.d.ts +9 -6
- package/lib/browser/types.js +11 -7
- package/lib/browser/user.js +13 -7
- package/lib/node/decode/user.d.ts.map +1 -1
- package/lib/node/decode/user.js +8 -5
- package/lib/node/driftClient.d.ts +15 -10
- package/lib/node/driftClient.d.ts.map +1 -1
- package/lib/node/driftClient.js +137 -23
- package/lib/node/marginCalculation.d.ts +0 -12
- package/lib/node/marginCalculation.d.ts.map +1 -1
- package/lib/node/marginCalculation.js +0 -20
- package/lib/node/math/margin.d.ts.map +1 -1
- package/lib/node/math/margin.js +1 -0
- package/lib/node/math/position.d.ts +1 -0
- package/lib/node/math/position.d.ts.map +1 -1
- package/lib/node/math/position.js +10 -2
- package/lib/node/math/spotBalance.d.ts.map +1 -1
- package/lib/node/swap/UnifiedSwapClient.d.ts.map +1 -1
- package/lib/node/swap/UnifiedSwapClient.js +1 -10
- package/lib/node/titan/titanClient.d.ts +4 -5
- package/lib/node/titan/titanClient.d.ts.map +1 -1
- package/lib/node/titan/titanClient.js +2 -16
- package/lib/node/types.d.ts +9 -6
- package/lib/node/types.d.ts.map +1 -1
- package/lib/node/types.js +11 -7
- package/lib/node/user.d.ts.map +1 -1
- package/lib/node/user.js +13 -7
- package/package.json +1 -1
- package/scripts/deposit-isolated-positions.ts +110 -0
- package/scripts/find-flagged-users.ts +216 -0
- package/scripts/single-grpc-client-test.ts +71 -21
- package/scripts/withdraw-isolated-positions.ts +174 -0
- package/src/decode/user.ts +14 -6
- package/src/driftClient.ts +297 -65
- package/src/margin/README.md +139 -0
- package/src/marginCalculation.ts +0 -32
- package/src/math/margin.ts +2 -3
- package/src/math/position.ts +12 -2
- package/src/math/spotBalance.ts +0 -1
- package/src/swap/UnifiedSwapClient.ts +2 -13
- package/src/titan/titanClient.ts +4 -28
- package/src/types.ts +11 -7
- package/src/user.ts +17 -8
- package/tests/dlob/helpers.ts +1 -1
- package/tests/user/test.ts +1 -1
package/src/driftClient.ts
CHANGED
|
@@ -57,7 +57,6 @@ import {
|
|
|
57
57
|
StateAccount,
|
|
58
58
|
SwapReduceOnly,
|
|
59
59
|
SignedMsgOrderParamsMessage,
|
|
60
|
-
TakerInfo,
|
|
61
60
|
TxParams,
|
|
62
61
|
UserAccount,
|
|
63
62
|
UserStatsAccount,
|
|
@@ -140,6 +139,7 @@ import {
|
|
|
140
139
|
BASE_PRECISION,
|
|
141
140
|
GOV_SPOT_MARKET_INDEX,
|
|
142
141
|
MARGIN_PRECISION,
|
|
142
|
+
MIN_I64,
|
|
143
143
|
ONE,
|
|
144
144
|
PERCENTAGE_PRECISION,
|
|
145
145
|
PRICE_PRECISION,
|
|
@@ -147,7 +147,11 @@ import {
|
|
|
147
147
|
QUOTE_SPOT_MARKET_INDEX,
|
|
148
148
|
ZERO,
|
|
149
149
|
} from './constants/numericConstants';
|
|
150
|
-
import {
|
|
150
|
+
import {
|
|
151
|
+
calculateClaimablePnl,
|
|
152
|
+
findDirectionToClose,
|
|
153
|
+
positionIsAvailable,
|
|
154
|
+
} from './math/position';
|
|
151
155
|
import { getSignedTokenAmount, getTokenAmount } from './math/spotBalance';
|
|
152
156
|
import { decodeName, DEFAULT_USER_NAME, encodeName } from './userName';
|
|
153
157
|
import { MMOraclePriceData, OraclePriceData } from './oracles/types';
|
|
@@ -200,6 +204,8 @@ import nacl from 'tweetnacl';
|
|
|
200
204
|
import { Slothash } from './slot/SlothashSubscriber';
|
|
201
205
|
import { getOracleId } from './oracles/oracleId';
|
|
202
206
|
import { SignedMsgOrderParams } from './types';
|
|
207
|
+
import { TakerInfo } from './types';
|
|
208
|
+
// BN is already imported globally in this file via other imports
|
|
203
209
|
import { sha256 } from '@noble/hashes/sha256';
|
|
204
210
|
import { getOracleConfidenceFromMMOracleData } from './oracles/utils';
|
|
205
211
|
import { ConstituentMap } from './constituentMap/constituentMap';
|
|
@@ -293,6 +299,46 @@ export class DriftClient {
|
|
|
293
299
|
return this._isSubscribed && this.accountSubscriber.isSubscribed;
|
|
294
300
|
}
|
|
295
301
|
|
|
302
|
+
private async getPrePlaceOrderIxs(
|
|
303
|
+
orderParams: OptionalOrderParams,
|
|
304
|
+
userAccount: UserAccount,
|
|
305
|
+
options?: { positionMaxLev?: number; isolatedPositionDepositAmount?: BN }
|
|
306
|
+
): Promise<TransactionInstruction[]> {
|
|
307
|
+
const preIxs: TransactionInstruction[] = [];
|
|
308
|
+
|
|
309
|
+
if (isVariant(orderParams.marketType, 'perp')) {
|
|
310
|
+
const { positionMaxLev, isolatedPositionDepositAmount } = options ?? {};
|
|
311
|
+
|
|
312
|
+
if (
|
|
313
|
+
isolatedPositionDepositAmount?.gt?.(ZERO) &&
|
|
314
|
+
this.isOrderIncreasingPosition(orderParams, userAccount.subAccountId)
|
|
315
|
+
) {
|
|
316
|
+
preIxs.push(
|
|
317
|
+
await this.getTransferIsolatedPerpPositionDepositIx(
|
|
318
|
+
isolatedPositionDepositAmount as BN,
|
|
319
|
+
orderParams.marketIndex,
|
|
320
|
+
userAccount.subAccountId
|
|
321
|
+
)
|
|
322
|
+
);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
if (positionMaxLev) {
|
|
326
|
+
const marginRatio = Math.floor(
|
|
327
|
+
(1 / positionMaxLev) * MARGIN_PRECISION.toNumber()
|
|
328
|
+
);
|
|
329
|
+
preIxs.push(
|
|
330
|
+
await this.getUpdateUserPerpPositionCustomMarginRatioIx(
|
|
331
|
+
orderParams.marketIndex,
|
|
332
|
+
marginRatio,
|
|
333
|
+
userAccount.subAccountId
|
|
334
|
+
)
|
|
335
|
+
);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
return preIxs;
|
|
340
|
+
}
|
|
341
|
+
|
|
296
342
|
public set isSubscribed(val: boolean) {
|
|
297
343
|
this._isSubscribed = val;
|
|
298
344
|
}
|
|
@@ -766,7 +812,6 @@ export class DriftClient {
|
|
|
766
812
|
|
|
767
813
|
return lookupTableAccount;
|
|
768
814
|
}
|
|
769
|
-
|
|
770
815
|
public async fetchAllLookupTableAccounts(): Promise<
|
|
771
816
|
AddressLookupTableAccount[]
|
|
772
817
|
> {
|
|
@@ -1771,7 +1816,6 @@ export class DriftClient {
|
|
|
1771
1816
|
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
1772
1817
|
return txSig;
|
|
1773
1818
|
}
|
|
1774
|
-
|
|
1775
1819
|
public async getUpdateUserCustomMarginRatioIx(
|
|
1776
1820
|
marginRatio: number,
|
|
1777
1821
|
subAccountId = 0
|
|
@@ -2580,7 +2624,6 @@ export class DriftClient {
|
|
|
2580
2624
|
this.mustIncludeSpotMarketIndexes.add(spotMarketIndex);
|
|
2581
2625
|
});
|
|
2582
2626
|
}
|
|
2583
|
-
|
|
2584
2627
|
getRemainingAccounts(params: RemainingAccountParams): AccountMeta[] {
|
|
2585
2628
|
const { oracleAccountMap, spotMarketAccountMap, perpMarketAccountMap } =
|
|
2586
2629
|
this.getRemainingAccountMapsForUsers(params.userAccounts);
|
|
@@ -3508,7 +3551,6 @@ export class DriftClient {
|
|
|
3508
3551
|
userAccountPublicKey,
|
|
3509
3552
|
};
|
|
3510
3553
|
}
|
|
3511
|
-
|
|
3512
3554
|
public async createInitializeUserAccountAndDepositCollateral(
|
|
3513
3555
|
amount: BN,
|
|
3514
3556
|
userTokenAccount: PublicKey,
|
|
@@ -4236,27 +4278,52 @@ export class DriftClient {
|
|
|
4236
4278
|
amount: BN,
|
|
4237
4279
|
perpMarketIndex: number,
|
|
4238
4280
|
subAccountId?: number,
|
|
4239
|
-
txParams?: TxParams
|
|
4281
|
+
txParams?: TxParams,
|
|
4282
|
+
trySettle?: boolean,
|
|
4283
|
+
noBuffer?: boolean
|
|
4240
4284
|
): Promise<TransactionSignature> {
|
|
4241
|
-
const
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
|
|
4249
|
-
),
|
|
4250
|
-
[],
|
|
4251
|
-
this.opts
|
|
4285
|
+
const ixs = [];
|
|
4286
|
+
const tokenAmountDeposited =
|
|
4287
|
+
this.getIsolatedPerpPositionTokenAmount(perpMarketIndex);
|
|
4288
|
+
const transferIx = await this.getTransferIsolatedPerpPositionDepositIx(
|
|
4289
|
+
amount,
|
|
4290
|
+
perpMarketIndex,
|
|
4291
|
+
subAccountId,
|
|
4292
|
+
noBuffer
|
|
4252
4293
|
);
|
|
4294
|
+
|
|
4295
|
+
const needsToSettle =
|
|
4296
|
+
amount.lt(tokenAmountDeposited.neg()) || amount.eq(MIN_I64) || trySettle;
|
|
4297
|
+
if (needsToSettle) {
|
|
4298
|
+
const settleIx = await this.settleMultiplePNLsIx(
|
|
4299
|
+
await getUserAccountPublicKey(
|
|
4300
|
+
this.program.programId,
|
|
4301
|
+
this.authority,
|
|
4302
|
+
subAccountId ?? this.activeSubAccountId
|
|
4303
|
+
),
|
|
4304
|
+
this.getUserAccount(subAccountId),
|
|
4305
|
+
[perpMarketIndex],
|
|
4306
|
+
SettlePnlMode.TRY_SETTLE
|
|
4307
|
+
);
|
|
4308
|
+
ixs.push(settleIx);
|
|
4309
|
+
}
|
|
4310
|
+
|
|
4311
|
+
ixs.push(transferIx);
|
|
4312
|
+
|
|
4313
|
+
const tx = await this.buildTransaction(ixs, txParams);
|
|
4314
|
+
const { txSig } = await this.sendTransaction(tx, [], {
|
|
4315
|
+
...this.opts,
|
|
4316
|
+
skipPreflight: true,
|
|
4317
|
+
});
|
|
4253
4318
|
return txSig;
|
|
4254
4319
|
}
|
|
4255
4320
|
|
|
4256
4321
|
public async getTransferIsolatedPerpPositionDepositIx(
|
|
4257
4322
|
amount: BN,
|
|
4258
4323
|
perpMarketIndex: number,
|
|
4259
|
-
subAccountId?: number
|
|
4324
|
+
subAccountId?: number,
|
|
4325
|
+
noAmountBuffer?: boolean,
|
|
4326
|
+
signingAuthority?: PublicKey
|
|
4260
4327
|
): Promise<TransactionInstruction> {
|
|
4261
4328
|
const userAccountPublicKey = await getUserAccountPublicKey(
|
|
4262
4329
|
this.program.programId,
|
|
@@ -4274,17 +4341,22 @@ export class DriftClient {
|
|
|
4274
4341
|
readablePerpMarketIndex: [perpMarketIndex],
|
|
4275
4342
|
});
|
|
4276
4343
|
|
|
4344
|
+
const amountWithBuffer =
|
|
4345
|
+
noAmountBuffer || amount.eq(MIN_I64)
|
|
4346
|
+
? amount
|
|
4347
|
+
: amount.add(amount.div(new BN(200))); // .5% buffer
|
|
4348
|
+
|
|
4277
4349
|
return await this.program.instruction.transferIsolatedPerpPositionDeposit(
|
|
4278
4350
|
spotMarketIndex,
|
|
4279
4351
|
perpMarketIndex,
|
|
4280
|
-
|
|
4352
|
+
amountWithBuffer,
|
|
4281
4353
|
{
|
|
4282
4354
|
accounts: {
|
|
4283
4355
|
state: await this.getStatePublicKey(),
|
|
4284
4356
|
spotMarketVault: spotMarketAccount.vault,
|
|
4285
4357
|
user: userAccountPublicKey,
|
|
4286
4358
|
userStats: this.getUserStatsAccountPublicKey(),
|
|
4287
|
-
authority: this.wallet.publicKey,
|
|
4359
|
+
authority: signingAuthority ?? this.wallet.publicKey,
|
|
4288
4360
|
},
|
|
4289
4361
|
remainingAccounts,
|
|
4290
4362
|
}
|
|
@@ -4298,20 +4370,83 @@ export class DriftClient {
|
|
|
4298
4370
|
subAccountId?: number,
|
|
4299
4371
|
txParams?: TxParams
|
|
4300
4372
|
): Promise<TransactionSignature> {
|
|
4373
|
+
const instructions =
|
|
4374
|
+
await this.getWithdrawFromIsolatedPerpPositionIxsBundle(
|
|
4375
|
+
amount,
|
|
4376
|
+
perpMarketIndex,
|
|
4377
|
+
subAccountId,
|
|
4378
|
+
userTokenAccount
|
|
4379
|
+
);
|
|
4301
4380
|
const { txSig } = await this.sendTransaction(
|
|
4302
|
-
await this.buildTransaction(
|
|
4303
|
-
await this.getWithdrawFromIsolatedPerpPositionIx(
|
|
4304
|
-
amount,
|
|
4305
|
-
perpMarketIndex,
|
|
4306
|
-
userTokenAccount,
|
|
4307
|
-
subAccountId
|
|
4308
|
-
),
|
|
4309
|
-
txParams
|
|
4310
|
-
)
|
|
4381
|
+
await this.buildTransaction(instructions, txParams)
|
|
4311
4382
|
);
|
|
4312
4383
|
return txSig;
|
|
4313
4384
|
}
|
|
4314
4385
|
|
|
4386
|
+
public async getWithdrawFromIsolatedPerpPositionIxsBundle(
|
|
4387
|
+
amount: BN,
|
|
4388
|
+
perpMarketIndex: number,
|
|
4389
|
+
subAccountId?: number,
|
|
4390
|
+
userTokenAccount?: PublicKey
|
|
4391
|
+
): Promise<TransactionInstruction[]> {
|
|
4392
|
+
const userAccountPublicKey = await getUserAccountPublicKey(
|
|
4393
|
+
this.program.programId,
|
|
4394
|
+
this.authority,
|
|
4395
|
+
subAccountId ?? this.activeSubAccountId
|
|
4396
|
+
);
|
|
4397
|
+
const userAccount = this.getUserAccount(subAccountId);
|
|
4398
|
+
|
|
4399
|
+
const tokenAmountDeposited =
|
|
4400
|
+
this.getIsolatedPerpPositionTokenAmount(perpMarketIndex);
|
|
4401
|
+
const isolatedPositionUnrealizedPnl = calculateClaimablePnl(
|
|
4402
|
+
this.getPerpMarketAccount(perpMarketIndex),
|
|
4403
|
+
this.getSpotMarketAccount(
|
|
4404
|
+
this.getPerpMarketAccount(perpMarketIndex).quoteSpotMarketIndex
|
|
4405
|
+
),
|
|
4406
|
+
userAccount.perpPositions.find((p) => p.marketIndex === perpMarketIndex),
|
|
4407
|
+
this.getOracleDataForSpotMarket(
|
|
4408
|
+
this.getPerpMarketAccount(perpMarketIndex).quoteSpotMarketIndex
|
|
4409
|
+
)
|
|
4410
|
+
);
|
|
4411
|
+
|
|
4412
|
+
const depositAmountPlusUnrealizedPnl = tokenAmountDeposited.add(
|
|
4413
|
+
isolatedPositionUnrealizedPnl
|
|
4414
|
+
);
|
|
4415
|
+
|
|
4416
|
+
const amountToWithdraw = amount.gt(depositAmountPlusUnrealizedPnl)
|
|
4417
|
+
? MIN_I64 // min i64
|
|
4418
|
+
: amount;
|
|
4419
|
+
let associatedTokenAccount = userTokenAccount;
|
|
4420
|
+
if (!associatedTokenAccount) {
|
|
4421
|
+
const perpMarketAccount = this.getPerpMarketAccount(perpMarketIndex);
|
|
4422
|
+
const quoteSpotMarketIndex = perpMarketAccount.quoteSpotMarketIndex;
|
|
4423
|
+
associatedTokenAccount = await this.getAssociatedTokenAccount(
|
|
4424
|
+
quoteSpotMarketIndex
|
|
4425
|
+
);
|
|
4426
|
+
}
|
|
4427
|
+
|
|
4428
|
+
const withdrawIx = await this.getWithdrawFromIsolatedPerpPositionIx(
|
|
4429
|
+
amountToWithdraw,
|
|
4430
|
+
perpMarketIndex,
|
|
4431
|
+
associatedTokenAccount,
|
|
4432
|
+
subAccountId
|
|
4433
|
+
);
|
|
4434
|
+
const ixs = [withdrawIx];
|
|
4435
|
+
|
|
4436
|
+
const needsToSettle =
|
|
4437
|
+
amount.gt(tokenAmountDeposited) && isolatedPositionUnrealizedPnl.gt(ZERO);
|
|
4438
|
+
if (needsToSettle) {
|
|
4439
|
+
const settleIx = await this.settleMultiplePNLsIx(
|
|
4440
|
+
userAccountPublicKey,
|
|
4441
|
+
userAccount,
|
|
4442
|
+
[perpMarketIndex],
|
|
4443
|
+
SettlePnlMode.TRY_SETTLE
|
|
4444
|
+
);
|
|
4445
|
+
ixs.push(settleIx);
|
|
4446
|
+
}
|
|
4447
|
+
return ixs;
|
|
4448
|
+
}
|
|
4449
|
+
|
|
4315
4450
|
public async getWithdrawFromIsolatedPerpPositionIx(
|
|
4316
4451
|
amount: BN,
|
|
4317
4452
|
perpMarketIndex: number,
|
|
@@ -4495,7 +4630,6 @@ export class DriftClient {
|
|
|
4495
4630
|
}
|
|
4496
4631
|
);
|
|
4497
4632
|
}
|
|
4498
|
-
|
|
4499
4633
|
public async getRemovePerpLpSharesIx(
|
|
4500
4634
|
marketIndex: number,
|
|
4501
4635
|
sharesToBurn?: BN,
|
|
@@ -4652,7 +4786,8 @@ export class DriftClient {
|
|
|
4652
4786
|
referrerInfo?: ReferrerInfo,
|
|
4653
4787
|
cancelExistingOrders?: boolean,
|
|
4654
4788
|
settlePnl?: boolean,
|
|
4655
|
-
positionMaxLev?: number
|
|
4789
|
+
positionMaxLev?: number,
|
|
4790
|
+
isolatedPositionDepositAmount?: BN
|
|
4656
4791
|
): Promise<{
|
|
4657
4792
|
cancelExistingOrdersTx?: Transaction | VersionedTransaction;
|
|
4658
4793
|
settlePnlTx?: Transaction | VersionedTransaction;
|
|
@@ -4680,18 +4815,25 @@ export class DriftClient {
|
|
|
4680
4815
|
|
|
4681
4816
|
const txKeys = Object.keys(ixPromisesForTxs);
|
|
4682
4817
|
|
|
4683
|
-
const
|
|
4684
|
-
|
|
4685
|
-
|
|
4686
|
-
|
|
4687
|
-
|
|
4688
|
-
|
|
4689
|
-
|
|
4690
|
-
|
|
4691
|
-
userAccount.subAccountId
|
|
4692
|
-
);
|
|
4818
|
+
const preIxs: TransactionInstruction[] = await this.getPrePlaceOrderIxs(
|
|
4819
|
+
orderParams,
|
|
4820
|
+
userAccount,
|
|
4821
|
+
{
|
|
4822
|
+
positionMaxLev,
|
|
4823
|
+
isolatedPositionDepositAmount,
|
|
4824
|
+
}
|
|
4825
|
+
);
|
|
4693
4826
|
|
|
4694
|
-
ixPromisesForTxs.marketOrderTx =
|
|
4827
|
+
ixPromisesForTxs.marketOrderTx = (async () => {
|
|
4828
|
+
const placeOrdersIx = await this.getPlaceOrdersIx(
|
|
4829
|
+
[orderParams, ...bracketOrdersParams],
|
|
4830
|
+
userAccount.subAccountId
|
|
4831
|
+
);
|
|
4832
|
+
if (preIxs.length) {
|
|
4833
|
+
return [...preIxs, placeOrdersIx] as unknown as TransactionInstruction;
|
|
4834
|
+
}
|
|
4835
|
+
return placeOrdersIx;
|
|
4836
|
+
})();
|
|
4695
4837
|
|
|
4696
4838
|
/* Cancel open orders in market if requested */
|
|
4697
4839
|
if (cancelExistingOrders && isVariant(orderParams.marketType, 'perp')) {
|
|
@@ -4809,12 +4951,32 @@ export class DriftClient {
|
|
|
4809
4951
|
public async placePerpOrder(
|
|
4810
4952
|
orderParams: OptionalOrderParams,
|
|
4811
4953
|
txParams?: TxParams,
|
|
4812
|
-
subAccountId?: number
|
|
4954
|
+
subAccountId?: number,
|
|
4955
|
+
isolatedPositionDepositAmount?: BN
|
|
4813
4956
|
): Promise<TransactionSignature> {
|
|
4957
|
+
const preIxs: TransactionInstruction[] = [];
|
|
4958
|
+
if (
|
|
4959
|
+
isolatedPositionDepositAmount?.gt?.(ZERO) &&
|
|
4960
|
+
this.isOrderIncreasingPosition(orderParams, subAccountId)
|
|
4961
|
+
) {
|
|
4962
|
+
preIxs.push(
|
|
4963
|
+
await this.getTransferIsolatedPerpPositionDepositIx(
|
|
4964
|
+
isolatedPositionDepositAmount as BN,
|
|
4965
|
+
orderParams.marketIndex,
|
|
4966
|
+
subAccountId
|
|
4967
|
+
)
|
|
4968
|
+
);
|
|
4969
|
+
}
|
|
4970
|
+
|
|
4814
4971
|
const { txSig, slot } = await this.sendTransaction(
|
|
4815
4972
|
await this.buildTransaction(
|
|
4816
4973
|
await this.getPlacePerpOrderIx(orderParams, subAccountId),
|
|
4817
|
-
txParams
|
|
4974
|
+
txParams,
|
|
4975
|
+
undefined,
|
|
4976
|
+
undefined,
|
|
4977
|
+
undefined,
|
|
4978
|
+
undefined,
|
|
4979
|
+
preIxs
|
|
4818
4980
|
),
|
|
4819
4981
|
[],
|
|
4820
4982
|
this.opts
|
|
@@ -5002,13 +5164,31 @@ export class DriftClient {
|
|
|
5002
5164
|
public async cancelOrder(
|
|
5003
5165
|
orderId?: number,
|
|
5004
5166
|
txParams?: TxParams,
|
|
5005
|
-
subAccountId?: number
|
|
5167
|
+
subAccountId?: number,
|
|
5168
|
+
overrides?: { withdrawIsolatedDepositAmount?: BN }
|
|
5006
5169
|
): Promise<TransactionSignature> {
|
|
5170
|
+
const cancelIx = await this.getCancelOrderIx(orderId, subAccountId);
|
|
5171
|
+
|
|
5172
|
+
const instructions: TransactionInstruction[] = [cancelIx];
|
|
5173
|
+
|
|
5174
|
+
if (overrides?.withdrawIsolatedDepositAmount !== undefined) {
|
|
5175
|
+
const order = this.getOrder(orderId, subAccountId);
|
|
5176
|
+
const perpMarketIndex = order?.marketIndex;
|
|
5177
|
+
const withdrawAmount = overrides.withdrawIsolatedDepositAmount;
|
|
5178
|
+
|
|
5179
|
+
if (withdrawAmount.gt(ZERO)) {
|
|
5180
|
+
const withdrawIxs =
|
|
5181
|
+
await this.getWithdrawFromIsolatedPerpPositionIxsBundle(
|
|
5182
|
+
withdrawAmount,
|
|
5183
|
+
perpMarketIndex,
|
|
5184
|
+
subAccountId
|
|
5185
|
+
);
|
|
5186
|
+
instructions.push(...withdrawIxs);
|
|
5187
|
+
}
|
|
5188
|
+
}
|
|
5189
|
+
|
|
5007
5190
|
const { txSig } = await this.sendTransaction(
|
|
5008
|
-
await this.buildTransaction(
|
|
5009
|
-
await this.getCancelOrderIx(orderId, subAccountId),
|
|
5010
|
-
txParams
|
|
5011
|
-
),
|
|
5191
|
+
await this.buildTransaction(instructions, txParams),
|
|
5012
5192
|
[],
|
|
5013
5193
|
this.opts
|
|
5014
5194
|
);
|
|
@@ -5242,7 +5422,8 @@ export class DriftClient {
|
|
|
5242
5422
|
params: OrderParams[],
|
|
5243
5423
|
txParams?: TxParams,
|
|
5244
5424
|
subAccountId?: number,
|
|
5245
|
-
optionalIxs?: TransactionInstruction[]
|
|
5425
|
+
optionalIxs?: TransactionInstruction[],
|
|
5426
|
+
isolatedPositionDepositAmount?: BN
|
|
5246
5427
|
): Promise<TransactionSignature> {
|
|
5247
5428
|
const { txSig } = await this.sendTransaction(
|
|
5248
5429
|
(
|
|
@@ -5250,7 +5431,8 @@ export class DriftClient {
|
|
|
5250
5431
|
params,
|
|
5251
5432
|
txParams,
|
|
5252
5433
|
subAccountId,
|
|
5253
|
-
optionalIxs
|
|
5434
|
+
optionalIxs,
|
|
5435
|
+
isolatedPositionDepositAmount
|
|
5254
5436
|
)
|
|
5255
5437
|
).placeOrdersTx,
|
|
5256
5438
|
[],
|
|
@@ -5264,10 +5446,29 @@ export class DriftClient {
|
|
|
5264
5446
|
params: OrderParams[],
|
|
5265
5447
|
txParams?: TxParams,
|
|
5266
5448
|
subAccountId?: number,
|
|
5267
|
-
optionalIxs?: TransactionInstruction[]
|
|
5449
|
+
optionalIxs?: TransactionInstruction[],
|
|
5450
|
+
isolatedPositionDepositAmount?: BN
|
|
5268
5451
|
) {
|
|
5269
5452
|
const lookupTableAccounts = await this.fetchAllLookupTableAccounts();
|
|
5270
5453
|
|
|
5454
|
+
const preIxs: TransactionInstruction[] = [];
|
|
5455
|
+
if (params?.length === 1) {
|
|
5456
|
+
const p = params[0];
|
|
5457
|
+
if (
|
|
5458
|
+
isVariant(p.marketType, 'perp') &&
|
|
5459
|
+
isolatedPositionDepositAmount?.gt?.(ZERO) &&
|
|
5460
|
+
this.isOrderIncreasingPosition(p, subAccountId)
|
|
5461
|
+
) {
|
|
5462
|
+
preIxs.push(
|
|
5463
|
+
await this.getTransferIsolatedPerpPositionDepositIx(
|
|
5464
|
+
isolatedPositionDepositAmount as BN,
|
|
5465
|
+
p.marketIndex,
|
|
5466
|
+
subAccountId
|
|
5467
|
+
)
|
|
5468
|
+
);
|
|
5469
|
+
}
|
|
5470
|
+
}
|
|
5471
|
+
|
|
5271
5472
|
const tx = await this.buildTransaction(
|
|
5272
5473
|
await this.getPlaceOrdersIx(params, subAccountId),
|
|
5273
5474
|
txParams,
|
|
@@ -5275,14 +5476,13 @@ export class DriftClient {
|
|
|
5275
5476
|
lookupTableAccounts,
|
|
5276
5477
|
undefined,
|
|
5277
5478
|
undefined,
|
|
5278
|
-
optionalIxs
|
|
5479
|
+
[...preIxs, ...(optionalIxs ?? [])]
|
|
5279
5480
|
);
|
|
5280
5481
|
|
|
5281
5482
|
return {
|
|
5282
5483
|
placeOrdersTx: tx,
|
|
5283
5484
|
};
|
|
5284
5485
|
}
|
|
5285
|
-
|
|
5286
5486
|
public async getPlaceOrdersIx(
|
|
5287
5487
|
params: OptionalOrderParams[],
|
|
5288
5488
|
subAccountId?: number,
|
|
@@ -5391,8 +5591,7 @@ export class DriftClient {
|
|
|
5391
5591
|
const marginRatio = Math.floor(
|
|
5392
5592
|
(1 / positionMaxLev) * MARGIN_PRECISION.toNumber()
|
|
5393
5593
|
);
|
|
5394
|
-
|
|
5395
|
-
// TODO: Handle multiple markets?
|
|
5594
|
+
// Keep existing behavior but note: prefer using getPostPlaceOrderIxs path
|
|
5396
5595
|
const setPositionMaxLevIxs =
|
|
5397
5596
|
await this.getUpdateUserPerpPositionCustomMarginRatioIx(
|
|
5398
5597
|
readablePerpMarketIndex[0],
|
|
@@ -7110,7 +7309,6 @@ export class DriftClient {
|
|
|
7110
7309
|
this.perpMarketLastSlotCache.set(orderParams.marketIndex, slot);
|
|
7111
7310
|
return txSig;
|
|
7112
7311
|
}
|
|
7113
|
-
|
|
7114
7312
|
public async preparePlaceAndTakePerpOrderWithAdditionalOrders(
|
|
7115
7313
|
orderParams: OptionalOrderParams,
|
|
7116
7314
|
makerInfo?: MakerInfo | MakerInfo[],
|
|
@@ -7122,7 +7320,8 @@ export class DriftClient {
|
|
|
7122
7320
|
settlePnl?: boolean,
|
|
7123
7321
|
exitEarlyIfSimFails?: boolean,
|
|
7124
7322
|
auctionDurationPercentage?: number,
|
|
7125
|
-
optionalIxs?: TransactionInstruction[]
|
|
7323
|
+
optionalIxs?: TransactionInstruction[],
|
|
7324
|
+
isolatedPositionDepositAmount?: BN
|
|
7126
7325
|
): Promise<{
|
|
7127
7326
|
placeAndTakeTx: Transaction | VersionedTransaction;
|
|
7128
7327
|
cancelExistingOrdersTx: Transaction | VersionedTransaction;
|
|
@@ -7156,6 +7355,20 @@ export class DriftClient {
|
|
|
7156
7355
|
subAccountId
|
|
7157
7356
|
);
|
|
7158
7357
|
|
|
7358
|
+
if (
|
|
7359
|
+
isVariant(orderParams.marketType, 'perp') &&
|
|
7360
|
+
isolatedPositionDepositAmount?.gt?.(ZERO) &&
|
|
7361
|
+
this.isOrderIncreasingPosition(orderParams, subAccountId)
|
|
7362
|
+
) {
|
|
7363
|
+
placeAndTakeIxs.push(
|
|
7364
|
+
await this.getTransferIsolatedPerpPositionDepositIx(
|
|
7365
|
+
isolatedPositionDepositAmount as BN,
|
|
7366
|
+
orderParams.marketIndex,
|
|
7367
|
+
subAccountId
|
|
7368
|
+
)
|
|
7369
|
+
);
|
|
7370
|
+
}
|
|
7371
|
+
|
|
7159
7372
|
placeAndTakeIxs.push(placeAndTakeIx);
|
|
7160
7373
|
|
|
7161
7374
|
if (bracketOrdersParams.length > 0) {
|
|
@@ -7166,6 +7379,11 @@ export class DriftClient {
|
|
|
7166
7379
|
placeAndTakeIxs.push(bracketOrdersIx);
|
|
7167
7380
|
}
|
|
7168
7381
|
|
|
7382
|
+
// Optional extra ixs can be appended at the front
|
|
7383
|
+
if (optionalIxs?.length) {
|
|
7384
|
+
placeAndTakeIxs.unshift(...optionalIxs);
|
|
7385
|
+
}
|
|
7386
|
+
|
|
7169
7387
|
const shouldUseSimulationComputeUnits =
|
|
7170
7388
|
txParams?.useSimulatedComputeUnits;
|
|
7171
7389
|
const shouldExitIfSimulationFails = exitEarlyIfSimFails;
|
|
@@ -7973,7 +8191,6 @@ export class DriftClient {
|
|
|
7973
8191
|
this.spotMarketLastSlotCache.set(QUOTE_SPOT_MARKET_INDEX, slot);
|
|
7974
8192
|
return txSig;
|
|
7975
8193
|
}
|
|
7976
|
-
|
|
7977
8194
|
public async getPlaceAndTakeSpotOrderIx(
|
|
7978
8195
|
orderParams: OptionalOrderParams,
|
|
7979
8196
|
fulfillmentConfig?: SerumV3FulfillmentConfigAccount,
|
|
@@ -8436,7 +8653,6 @@ export class DriftClient {
|
|
|
8436
8653
|
bitFlags?: number;
|
|
8437
8654
|
policy?: ModifyOrderPolicy;
|
|
8438
8655
|
maxTs?: BN;
|
|
8439
|
-
txParams?: TxParams;
|
|
8440
8656
|
},
|
|
8441
8657
|
subAccountId?: number
|
|
8442
8658
|
): Promise<TransactionInstruction> {
|
|
@@ -8962,7 +9178,6 @@ export class DriftClient {
|
|
|
8962
9178
|
this.perpMarketLastSlotCache.set(marketIndex, slot);
|
|
8963
9179
|
return txSig;
|
|
8964
9180
|
}
|
|
8965
|
-
|
|
8966
9181
|
public async getLiquidatePerpIx(
|
|
8967
9182
|
userAccountPublicKey: PublicKey,
|
|
8968
9183
|
userAccount: UserAccount,
|
|
@@ -9753,7 +9968,6 @@ export class DriftClient {
|
|
|
9753
9968
|
}
|
|
9754
9969
|
);
|
|
9755
9970
|
}
|
|
9756
|
-
|
|
9757
9971
|
public async resolveSpotBankruptcy(
|
|
9758
9972
|
userAccountPublicKey: PublicKey,
|
|
9759
9973
|
userAccount: UserAccount,
|
|
@@ -10590,7 +10804,6 @@ export class DriftClient {
|
|
|
10590
10804
|
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
10591
10805
|
return txSig;
|
|
10592
10806
|
}
|
|
10593
|
-
|
|
10594
10807
|
public async getSettleRevenueToInsuranceFundIx(
|
|
10595
10808
|
spotMarketIndex: number
|
|
10596
10809
|
): Promise<TransactionInstruction> {
|
|
@@ -11394,7 +11607,6 @@ export class DriftClient {
|
|
|
11394
11607
|
);
|
|
11395
11608
|
return config as ProtectedMakerModeConfig;
|
|
11396
11609
|
}
|
|
11397
|
-
|
|
11398
11610
|
public async updateUserProtectedMakerOrders(
|
|
11399
11611
|
subAccountId: number,
|
|
11400
11612
|
protectedOrders: boolean,
|
|
@@ -12788,4 +13000,24 @@ export class DriftClient {
|
|
|
12788
13000
|
forceVersionedTransaction,
|
|
12789
13001
|
});
|
|
12790
13002
|
}
|
|
13003
|
+
|
|
13004
|
+
isOrderIncreasingPosition(
|
|
13005
|
+
orderParams: OptionalOrderParams,
|
|
13006
|
+
subAccountId: number
|
|
13007
|
+
): boolean {
|
|
13008
|
+
const userAccount = this.getUserAccount(subAccountId);
|
|
13009
|
+
const perpPosition = userAccount.perpPositions.find(
|
|
13010
|
+
(p) => p.marketIndex === orderParams.marketIndex
|
|
13011
|
+
);
|
|
13012
|
+
if (!perpPosition) return true;
|
|
13013
|
+
|
|
13014
|
+
const currentBase = perpPosition.baseAssetAmount;
|
|
13015
|
+
if (currentBase.eq(ZERO)) return true;
|
|
13016
|
+
|
|
13017
|
+
const orderBaseAmount = isVariant(orderParams.direction, 'long')
|
|
13018
|
+
? orderParams.baseAssetAmount
|
|
13019
|
+
: orderParams.baseAssetAmount.neg();
|
|
13020
|
+
|
|
13021
|
+
return currentBase.add(orderBaseAmount).abs().gt(currentBase.abs());
|
|
13022
|
+
}
|
|
12791
13023
|
}
|