@@ -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 ,
@@ -185,6 +184,8 @@ import nacl from 'tweetnacl';
185
184
import { Slothash } from './slot/SlothashSubscriber' ;
186
185
import { getOracleId } from './oracles/oracleId' ;
187
186
import { SignedMsgOrderParams } from './types' ;
187
+ import { TakerInfo } from './types' ;
188
+ // BN is already imported globally in this file via other imports
188
189
import { sha256 } from '@noble/hashes/sha256' ;
189
190
190
191
type RemainingAccountParams = {
@@ -254,6 +255,69 @@ export class DriftClient {
254
255
return this . _isSubscribed && this . accountSubscriber . isSubscribed ;
255
256
}
256
257
258
+ public async getDepositIntoIsolatedPerpPositionIx ( {
259
+ perpMarketIndex,
260
+ amount,
261
+ spotMarketIndex,
262
+ subAccountId,
263
+ userTokenAccount,
264
+ } : {
265
+ perpMarketIndex : number ;
266
+ amount : BN ;
267
+ spotMarketIndex ?: number ; // defaults to perp.quoteSpotMarketIndex
268
+ subAccountId ?: number ;
269
+ userTokenAccount ?: PublicKey ; // defaults ATA for spot market mint
270
+ } ) : Promise < TransactionInstruction > {
271
+ const user = await this . getUserAccountPublicKey ( subAccountId ) ;
272
+ const userStats = this . getUserStatsAccountPublicKey ( ) ;
273
+ const statePk = await this . getStatePublicKey ( ) ;
274
+ const perp = this . getPerpMarketAccount ( perpMarketIndex ) ;
275
+ const spotIndex = spotMarketIndex ?? perp . quoteSpotMarketIndex ;
276
+ const spot = this . getSpotMarketAccount ( spotIndex ) ;
277
+
278
+ const remainingAccounts = this . getRemainingAccounts ( {
279
+ userAccounts : [ this . getUserAccount ( subAccountId ) ] ,
280
+ readablePerpMarketIndex : perpMarketIndex ,
281
+ writableSpotMarketIndexes : [ spotIndex ] ,
282
+ } ) ;
283
+
284
+ // token program and transfer hook mints need to be present for deposit
285
+ this . addTokenMintToRemainingAccounts ( spot , remainingAccounts ) ;
286
+ if ( this . isTransferHook ( spot ) ) {
287
+ await this . addExtraAccountMetasToRemainingAccounts (
288
+ spot . mint ,
289
+ remainingAccounts
290
+ ) ;
291
+ }
292
+
293
+ const tokenProgram = this . getTokenProgramForSpotMarket ( spot ) ;
294
+ const ata =
295
+ userTokenAccount ??
296
+ ( await this . getAssociatedTokenAccount (
297
+ spotIndex ,
298
+ false ,
299
+ tokenProgram
300
+ ) ) ;
301
+
302
+ return await this . program . instruction . depositIntoIsolatedPerpPosition (
303
+ spotIndex ,
304
+ perpMarketIndex ,
305
+ amount ,
306
+ {
307
+ accounts : {
308
+ state : statePk ,
309
+ user,
310
+ userStats,
311
+ authority : this . wallet . publicKey ,
312
+ spotMarketVault : spot . vault ,
313
+ userTokenAccount : ata ,
314
+ tokenProgram,
315
+ } ,
316
+ remainingAccounts,
317
+ }
318
+ ) ;
319
+ }
320
+
257
321
public set isSubscribed ( val : boolean ) {
258
322
this . _isSubscribed = val ;
259
323
}
@@ -717,7 +781,6 @@ export class DriftClient {
717
781
718
782
return lookupTableAccount ;
719
783
}
720
-
721
784
public async fetchAllLookupTableAccounts ( ) : Promise <
722
785
AddressLookupTableAccount [ ]
723
786
> {
@@ -1495,7 +1558,6 @@ export class DriftClient {
1495
1558
const { txSig } = await this . sendTransaction ( tx , [ ] , this . opts ) ;
1496
1559
return txSig ;
1497
1560
}
1498
-
1499
1561
public async getUpdateUserCustomMarginRatioIx (
1500
1562
marginRatio : number ,
1501
1563
subAccountId = 0
@@ -2196,7 +2258,6 @@ export class DriftClient {
2196
2258
this . mustIncludeSpotMarketIndexes . add ( spotMarketIndex ) ;
2197
2259
} ) ;
2198
2260
}
2199
-
2200
2261
getRemainingAccounts ( params : RemainingAccountParams ) : AccountMeta [ ] {
2201
2262
const { oracleAccountMap, spotMarketAccountMap, perpMarketAccountMap } =
2202
2263
this . getRemainingAccountMapsForUsers ( params . userAccounts ) ;
@@ -2977,7 +3038,6 @@ export class DriftClient {
2977
3038
userAccountPublicKey,
2978
3039
} ;
2979
3040
}
2980
-
2981
3041
public async createInitializeUserAccountAndDepositCollateral (
2982
3042
amount : BN ,
2983
3043
userTokenAccount : PublicKey ,
@@ -3777,7 +3837,6 @@ export class DriftClient {
3777
3837
}
3778
3838
) ;
3779
3839
}
3780
-
3781
3840
public async getRemovePerpLpSharesIx (
3782
3841
marketIndex : number ,
3783
3842
sharesToBurn ?: BN ,
@@ -3933,7 +3992,8 @@ export class DriftClient {
3933
3992
bracketOrdersParams = new Array < OptionalOrderParams > ( ) ,
3934
3993
referrerInfo ?: ReferrerInfo ,
3935
3994
cancelExistingOrders ?: boolean ,
3936
- settlePnl ?: boolean
3995
+ settlePnl ?: boolean ,
3996
+ isolatedPositionDepositAmount ?: BN
3937
3997
) : Promise < {
3938
3998
cancelExistingOrdersTx ?: Transaction | VersionedTransaction ;
3939
3999
settlePnlTx ?: Transaction | VersionedTransaction ;
@@ -3958,10 +4018,32 @@ export class DriftClient {
3958
4018
3959
4019
const txKeys = Object . keys ( ixPromisesForTxs ) ;
3960
4020
3961
- ixPromisesForTxs . marketOrderTx = this . getPlaceOrdersIx (
3962
- [ orderParams , ...bracketOrdersParams ] ,
3963
- userAccount . subAccountId
3964
- ) ;
4021
+
4022
+ const preIxs : TransactionInstruction [ ] = [ ] ;
4023
+ if ( isVariant ( orderParams . marketType , 'perp' ) && isolatedPositionDepositAmount ?. gt ?.( ZERO ) ) {
4024
+ preIxs . push (
4025
+ await this . getDepositIntoIsolatedPerpPositionIx ( {
4026
+ perpMarketIndex : orderParams . marketIndex ,
4027
+ amount : isolatedPositionDepositAmount as BN ,
4028
+ subAccountId : userAccount . subAccountId ,
4029
+ } )
4030
+ ) ;
4031
+ }
4032
+
4033
+
4034
+ ixPromisesForTxs . marketOrderTx = ( async ( ) => {
4035
+ const placeOrdersIx = await this . getPlaceOrdersIx (
4036
+ [ orderParams , ...bracketOrdersParams ] ,
4037
+ userAccount . subAccountId
4038
+ ) ;
4039
+ if ( preIxs . length ) {
4040
+ return [
4041
+ ...preIxs ,
4042
+ placeOrdersIx ,
4043
+ ] as unknown as TransactionInstruction ;
4044
+ }
4045
+ return placeOrdersIx ;
4046
+ } ) ( ) ;
3965
4047
3966
4048
/* Cancel open orders in market if requested */
3967
4049
if ( cancelExistingOrders && isVariant ( orderParams . marketType , 'perp' ) ) {
@@ -4076,12 +4158,29 @@ export class DriftClient {
4076
4158
public async placePerpOrder (
4077
4159
orderParams : OptionalOrderParams ,
4078
4160
txParams ?: TxParams ,
4079
- subAccountId ?: number
4161
+ subAccountId ?: number ,
4162
+ isolatedPositionDepositAmount ?: BN
4080
4163
) : Promise < TransactionSignature > {
4164
+ const preIxs : TransactionInstruction [ ] = [ ] ;
4165
+ if ( isolatedPositionDepositAmount ?. gt ?.( ZERO ) ) {
4166
+ preIxs . push (
4167
+ await this . getDepositIntoIsolatedPerpPositionIx ( {
4168
+ perpMarketIndex : orderParams . marketIndex ,
4169
+ amount : isolatedPositionDepositAmount as BN ,
4170
+ subAccountId,
4171
+ } )
4172
+ ) ;
4173
+ }
4174
+
4081
4175
const { txSig, slot } = await this . sendTransaction (
4082
4176
await this . buildTransaction (
4083
4177
await this . getPlacePerpOrderIx ( orderParams , subAccountId ) ,
4084
- txParams
4178
+ txParams ,
4179
+ undefined ,
4180
+ undefined ,
4181
+ undefined ,
4182
+ undefined ,
4183
+ preIxs
4085
4184
) ,
4086
4185
[ ] ,
4087
4186
this . opts
@@ -4435,6 +4534,7 @@ export class DriftClient {
4435
4534
useMarketLastSlotCache : true ,
4436
4535
} ) ;
4437
4536
4537
+
4438
4538
return await this . program . instruction . cancelOrders (
4439
4539
marketType ?? null ,
4440
4540
marketIndex ?? null ,
@@ -4478,7 +4578,8 @@ export class DriftClient {
4478
4578
params : OrderParams [ ] ,
4479
4579
txParams ?: TxParams ,
4480
4580
subAccountId ?: number ,
4481
- optionalIxs ?: TransactionInstruction [ ]
4581
+ optionalIxs ?: TransactionInstruction [ ] ,
4582
+ isolatedPositionDepositAmount ?: BN
4482
4583
) : Promise < TransactionSignature > {
4483
4584
const { txSig } = await this . sendTransaction (
4484
4585
(
@@ -4500,25 +4601,39 @@ export class DriftClient {
4500
4601
params : OrderParams [ ] ,
4501
4602
txParams ?: TxParams ,
4502
4603
subAccountId ?: number ,
4503
- optionalIxs ?: TransactionInstruction [ ]
4604
+ optionalIxs ?: TransactionInstruction [ ] ,
4605
+ isolatedPositionDepositAmount ?: BN
4504
4606
) {
4505
4607
const lookupTableAccounts = await this . fetchAllLookupTableAccounts ( ) ;
4506
4608
4609
+ const preIxs : TransactionInstruction [ ] = [ ] ;
4610
+ if ( params ?. length === 1 ) {
4611
+ const p = params [ 0 ] ;
4612
+ if ( isVariant ( p . marketType , 'perp' ) && isolatedPositionDepositAmount ?. gt ?.( ZERO ) ) {
4613
+ preIxs . push (
4614
+ await this . getDepositIntoIsolatedPerpPositionIx ( {
4615
+ perpMarketIndex : p . marketIndex ,
4616
+ amount : isolatedPositionDepositAmount as BN ,
4617
+ subAccountId,
4618
+ } )
4619
+ ) ;
4620
+ }
4621
+ }
4622
+
4507
4623
const tx = await this . buildTransaction (
4508
4624
await this . getPlaceOrdersIx ( params , subAccountId ) ,
4509
4625
txParams ,
4510
4626
undefined ,
4511
4627
lookupTableAccounts ,
4512
4628
undefined ,
4513
4629
undefined ,
4514
- optionalIxs
4630
+ [ ... preIxs , ... ( optionalIxs ?? [ ] ) ]
4515
4631
) ;
4516
4632
4517
4633
return {
4518
4634
placeOrdersTx : tx ,
4519
4635
} ;
4520
4636
}
4521
-
4522
4637
public async getPlaceOrdersIx (
4523
4638
params : OptionalOrderParams [ ] ,
4524
4639
subAccountId ?: number
@@ -5256,7 +5371,6 @@ export class DriftClient {
5256
5371
5257
5372
return txSig ;
5258
5373
}
5259
-
5260
5374
public async getJupiterSwapIxV6 ( {
5261
5375
jupiterClient,
5262
5376
outMarketIndex,
@@ -5926,7 +6040,6 @@ export class DriftClient {
5926
6040
this . perpMarketLastSlotCache . set ( orderParams . marketIndex , slot ) ;
5927
6041
return txSig ;
5928
6042
}
5929
-
5930
6043
public async preparePlaceAndTakePerpOrderWithAdditionalOrders (
5931
6044
orderParams : OptionalOrderParams ,
5932
6045
makerInfo ?: MakerInfo | MakerInfo [ ] ,
@@ -5938,7 +6051,8 @@ export class DriftClient {
5938
6051
settlePnl ?: boolean ,
5939
6052
exitEarlyIfSimFails ?: boolean ,
5940
6053
auctionDurationPercentage ?: number ,
5941
- optionalIxs ?: TransactionInstruction [ ]
6054
+ optionalIxs ?: TransactionInstruction [ ] ,
6055
+ isolatedPositionDepositAmount ?: BN
5942
6056
) : Promise < {
5943
6057
placeAndTakeTx : Transaction | VersionedTransaction ;
5944
6058
cancelExistingOrdersTx : Transaction | VersionedTransaction ;
@@ -5972,6 +6086,16 @@ export class DriftClient {
5972
6086
subAccountId
5973
6087
) ;
5974
6088
6089
+ if ( isVariant ( orderParams . marketType , 'perp' ) && isolatedPositionDepositAmount ?. gt ?.( ZERO ) ) {
6090
+ placeAndTakeIxs . push (
6091
+ await this . getDepositIntoIsolatedPerpPositionIx ( {
6092
+ perpMarketIndex : orderParams . marketIndex ,
6093
+ amount : isolatedPositionDepositAmount as BN ,
6094
+ subAccountId,
6095
+ } )
6096
+ ) ;
6097
+ }
6098
+
5975
6099
placeAndTakeIxs . push ( placeAndTakeIx ) ;
5976
6100
5977
6101
if ( bracketOrdersParams . length > 0 ) {
@@ -5982,6 +6106,11 @@ export class DriftClient {
5982
6106
placeAndTakeIxs . push ( bracketOrdersIx ) ;
5983
6107
}
5984
6108
6109
+ // Optional extra ixs can be appended at the front
6110
+ if ( optionalIxs ?. length ) {
6111
+ placeAndTakeIxs . unshift ( ...optionalIxs ) ;
6112
+ }
6113
+
5985
6114
const shouldUseSimulationComputeUnits =
5986
6115
txParams ?. useSimulatedComputeUnits ;
5987
6116
const shouldExitIfSimulationFails = exitEarlyIfSimFails ;
@@ -6670,7 +6799,6 @@ export class DriftClient {
6670
6799
this . spotMarketLastSlotCache . set ( QUOTE_SPOT_MARKET_INDEX , slot ) ;
6671
6800
return txSig ;
6672
6801
}
6673
-
6674
6802
public async getPlaceAndTakeSpotOrderIx (
6675
6803
orderParams : OptionalOrderParams ,
6676
6804
fulfillmentConfig ?: SerumV3FulfillmentConfigAccount ,
@@ -7115,7 +7243,6 @@ export class DriftClient {
7115
7243
bitFlags ?: number ;
7116
7244
policy ?: ModifyOrderPolicy ;
7117
7245
maxTs ?: BN ;
7118
- txParams ?: TxParams ;
7119
7246
} ,
7120
7247
subAccountId ?: number
7121
7248
) : Promise < TransactionInstruction > {
@@ -7454,7 +7581,6 @@ export class DriftClient {
7454
7581
this . perpMarketLastSlotCache . set ( marketIndex , slot ) ;
7455
7582
return txSig ;
7456
7583
}
7457
-
7458
7584
public async getLiquidatePerpIx (
7459
7585
userAccountPublicKey : PublicKey ,
7460
7586
userAccount : UserAccount ,
@@ -8245,7 +8371,6 @@ export class DriftClient {
8245
8371
}
8246
8372
) ;
8247
8373
}
8248
-
8249
8374
public async resolveSpotBankruptcy (
8250
8375
userAccountPublicKey : PublicKey ,
8251
8376
userAccount : UserAccount ,
@@ -9040,7 +9165,6 @@ export class DriftClient {
9040
9165
const { txSig } = await this . sendTransaction ( tx , [ ] , this . opts ) ;
9041
9166
return txSig ;
9042
9167
}
9043
-
9044
9168
public async getSettleRevenueToInsuranceFundIx (
9045
9169
spotMarketIndex : number
9046
9170
) : Promise < TransactionInstruction > {
@@ -9830,7 +9954,6 @@ export class DriftClient {
9830
9954
) ;
9831
9955
return config as ProtectedMakerModeConfig ;
9832
9956
}
9833
-
9834
9957
public async updateUserProtectedMakerOrders (
9835
9958
subAccountId : number ,
9836
9959
protectedOrders : boolean ,
@@ -10048,4 +10171,4 @@ export class DriftClient {
10048
10171
forceVersionedTransaction,
10049
10172
} ) ;
10050
10173
}
10051
- }
10174
+ }
0 commit comments