@drift-labs/sdk 0.2.0-master.25 → 0.2.0-master.26
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/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +13 -13
- package/lib/accounts/pollingClearingHouseAccountSubscriber.js +27 -27
- package/lib/accounts/types.d.ts +8 -9
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +14 -14
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +35 -34
- package/lib/addresses/pda.d.ts +7 -6
- package/lib/addresses/pda.js +31 -27
- package/lib/admin.d.ts +9 -6
- package/lib/admin.js +83 -42
- package/lib/clearingHouse.d.ts +69 -42
- package/lib/clearingHouse.js +753 -277
- package/lib/clearingHouseConfig.d.ts +2 -2
- package/lib/clearingHouseUser.d.ts +16 -16
- package/lib/clearingHouseUser.js +139 -119
- package/lib/config.d.ts +7 -7
- package/lib/config.js +20 -20
- package/lib/constants/numericConstants.d.ts +12 -12
- package/lib/constants/numericConstants.js +13 -13
- package/lib/constants/{markets.d.ts → perpMarkets.d.ts} +5 -5
- package/{src/constants/markets.js → lib/constants/perpMarkets.js} +4 -4
- package/lib/constants/{banks.d.ts → spotMarkets.d.ts} +6 -6
- package/lib/constants/{banks.js → spotMarkets.js} +16 -16
- package/lib/events/types.d.ts +2 -1
- package/lib/events/types.js +1 -0
- package/lib/examples/makeTradeExample.js +7 -7
- package/lib/idl/clearing_house.json +1008 -279
- package/lib/index.d.ts +5 -3
- package/lib/index.js +5 -3
- package/lib/math/amm.d.ts +2 -2
- package/lib/math/amm.js +1 -1
- package/lib/math/funding.d.ts +6 -6
- package/lib/math/funding.js +2 -1
- package/lib/math/margin.d.ts +4 -4
- package/lib/math/margin.js +18 -11
- package/lib/math/market.d.ts +10 -9
- package/lib/math/market.js +29 -6
- package/lib/math/oracles.d.ts +2 -1
- package/lib/math/oracles.js +11 -1
- package/lib/math/orders.d.ts +5 -5
- package/lib/math/position.d.ts +13 -13
- package/lib/math/position.js +19 -19
- package/lib/math/spotBalance.d.ts +19 -0
- package/lib/math/spotBalance.js +176 -0
- package/lib/math/spotMarket.d.ts +4 -0
- package/lib/math/spotMarket.js +8 -0
- package/lib/math/spotPosition.d.ts +2 -0
- package/lib/math/spotPosition.js +8 -0
- package/lib/math/state.js +2 -2
- package/lib/math/trade.d.ts +4 -4
- package/lib/orderParams.d.ts +4 -4
- package/lib/orderParams.js +12 -4
- package/lib/serum/serumSubscriber.d.ts +23 -0
- package/lib/serum/serumSubscriber.js +41 -0
- package/lib/serum/types.d.ts +11 -0
- package/lib/serum/types.js +2 -0
- package/lib/tx/retryTxSender.d.ts +1 -1
- package/lib/tx/retryTxSender.js +4 -2
- package/lib/tx/types.d.ts +1 -1
- package/lib/types.d.ts +123 -33
- package/lib/types.js +31 -9
- package/my-script/.env +7 -0
- package/my-script/getUserStats.ts +106 -0
- package/my-script/multiConnections.ts +119 -0
- package/my-script/test-regex.ts +11 -0
- package/my-script/utils.ts +52 -0
- package/package.json +1 -1
- package/src/accounts/bulkAccountLoader.js +249 -0
- package/src/accounts/bulkUserStatsSubscription.js +75 -0
- package/src/accounts/bulkUserSubscription.js +75 -0
- package/src/accounts/fetch.js +92 -0
- package/src/accounts/pollingClearingHouseAccountSubscriber.js +465 -0
- package/src/accounts/pollingClearingHouseAccountSubscriber.ts +38 -38
- package/src/accounts/pollingOracleSubscriber.js +156 -0
- package/src/accounts/pollingTokenAccountSubscriber.js +141 -0
- package/src/accounts/pollingUserAccountSubscriber.js +208 -0
- package/src/accounts/pollingUserStatsAccountSubscriber.js +208 -0
- package/src/accounts/types.js +28 -0
- package/src/accounts/types.ts +11 -9
- package/src/accounts/utils.js +7 -0
- package/src/accounts/webSocketAccountSubscriber.js +138 -0
- package/src/accounts/webSocketClearingHouseAccountSubscriber.js +433 -0
- package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +59 -52
- package/src/accounts/webSocketUserAccountSubscriber.js +113 -0
- package/src/accounts/webSocketUserStatsAccountSubsriber.js +113 -0
- package/src/addresses/pda.js +186 -0
- package/src/addresses/pda.ts +49 -44
- package/src/admin.js +1284 -0
- package/src/admin.ts +140 -47
- package/src/assert/assert.js +1 -1
- package/src/clearingHouse.js +3433 -0
- package/src/clearingHouse.ts +1083 -378
- package/src/clearingHouseConfig.js +2 -0
- package/src/clearingHouseConfig.ts +2 -2
- package/src/clearingHouseUser.js +874 -0
- package/src/clearingHouseUser.ts +232 -168
- package/src/clearingHouseUserConfig.js +2 -0
- package/src/clearingHouseUserStats.js +115 -0
- package/src/clearingHouseUserStatsConfig.js +2 -0
- package/src/config.js +80 -0
- package/src/config.ts +29 -29
- package/src/constants/numericConstants.js +18 -11
- package/src/constants/numericConstants.ts +17 -15
- package/{lib/constants/markets.js → src/constants/perpMarkets.js} +11 -11
- package/src/constants/{markets.ts → perpMarkets.ts} +5 -5
- package/src/constants/spotMarkets.js +51 -0
- package/src/constants/{banks.ts → spotMarkets.ts} +19 -19
- package/src/events/eventList.js +66 -23
- package/src/events/eventSubscriber.js +202 -0
- package/src/events/fetchLogs.js +117 -0
- package/src/events/pollingLogProvider.js +113 -0
- package/src/events/sort.js +41 -0
- package/src/events/txEventCache.js +22 -19
- package/src/events/types.js +25 -0
- package/src/events/types.ts +3 -0
- package/src/events/webSocketLogProvider.js +76 -0
- package/src/examples/makeTradeExample.ts +10 -8
- package/src/factory/bigNum.js +183 -180
- package/src/factory/oracleClient.js +9 -9
- package/src/idl/clearing_house.json +1008 -279
- package/src/index.js +75 -0
- package/src/index.ts +5 -3
- package/src/math/amm.js +422 -0
- package/src/math/amm.ts +6 -3
- package/src/math/auction.js +10 -10
- package/src/math/conversion.js +4 -3
- package/src/math/funding.js +223 -175
- package/src/math/funding.ts +7 -7
- package/src/math/insurance.js +27 -0
- package/src/math/margin.js +77 -0
- package/src/math/margin.ts +34 -23
- package/src/math/market.js +105 -0
- package/src/math/market.ts +71 -19
- package/src/math/oracles.js +40 -10
- package/src/math/oracles.ts +18 -1
- package/src/math/orders.js +153 -0
- package/src/math/orders.ts +5 -5
- package/src/math/position.js +172 -0
- package/src/math/position.ts +31 -31
- package/src/math/repeg.js +40 -40
- package/src/math/spotBalance.js +176 -0
- package/src/math/spotBalance.ts +290 -0
- package/src/math/spotMarket.js +8 -0
- package/src/math/spotMarket.ts +9 -0
- package/src/math/spotPosition.js +8 -0
- package/src/math/spotPosition.ts +6 -0
- package/src/math/state.ts +2 -2
- package/src/math/trade.js +81 -74
- package/src/math/trade.ts +4 -4
- package/src/math/utils.js +8 -7
- package/src/oracles/oracleClientCache.js +10 -9
- package/src/oracles/pythClient.js +52 -17
- package/src/oracles/quoteAssetOracleClient.js +44 -13
- package/src/oracles/switchboardClient.js +69 -37
- package/src/oracles/types.js +1 -1
- package/src/orderParams.js +14 -6
- package/src/orderParams.ts +16 -8
- package/src/serum/serumSubscriber.js +102 -0
- package/src/serum/serumSubscriber.ts +80 -0
- package/src/serum/types.js +2 -0
- package/src/serum/types.ts +13 -0
- package/src/slot/SlotSubscriber.js +67 -20
- package/src/token/index.js +4 -4
- package/src/tokenFaucet.js +288 -154
- package/src/tx/retryTxSender.js +280 -0
- package/src/tx/retryTxSender.ts +5 -2
- package/src/tx/types.js +1 -1
- package/src/tx/types.ts +2 -1
- package/src/tx/utils.js +7 -6
- package/src/types.js +216 -0
- package/src/types.ts +110 -33
- package/src/userName.js +5 -5
- package/src/util/computeUnits.js +46 -11
- package/src/util/promiseTimeout.js +5 -5
- package/src/util/tps.js +46 -12
- package/src/wallet.js +55 -18
- package/lib/math/bankBalance.d.ts +0 -15
- package/lib/math/bankBalance.js +0 -150
- package/src/addresses/marketAddresses.js +0 -26
- package/src/constants/banks.js +0 -42
- package/src/examples/makeTradeExample.js +0 -80
- package/src/math/bankBalance.ts +0 -258
- package/src/math/state.js +0 -15
- package/src/math/utils.js.map +0 -1
- package/src/util/getTokenAddress.js +0 -9
package/src/clearingHouse.ts
CHANGED
|
@@ -5,17 +5,19 @@ import {
|
|
|
5
5
|
IWallet,
|
|
6
6
|
PositionDirection,
|
|
7
7
|
UserAccount,
|
|
8
|
-
|
|
8
|
+
PerpMarketAccount,
|
|
9
9
|
OrderParams,
|
|
10
10
|
Order,
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
SpotMarketAccount,
|
|
12
|
+
SpotPosition,
|
|
13
13
|
MakerInfo,
|
|
14
14
|
TakerInfo,
|
|
15
15
|
OptionalOrderParams,
|
|
16
16
|
DefaultOrderParams,
|
|
17
17
|
OrderType,
|
|
18
18
|
ReferrerInfo,
|
|
19
|
+
MarketType,
|
|
20
|
+
SerumV3FulfillmentConfigAccount,
|
|
19
21
|
} from './types';
|
|
20
22
|
import * as anchor from '@project-serum/anchor';
|
|
21
23
|
import clearingHouseIDL from './idl/clearing_house.json';
|
|
@@ -43,6 +45,8 @@ import {
|
|
|
43
45
|
getClearingHouseStateAccountPublicKey,
|
|
44
46
|
getInsuranceFundStakeAccountPublicKey,
|
|
45
47
|
getMarketPublicKey,
|
|
48
|
+
getSerumFulfillmentConfigPublicKey,
|
|
49
|
+
getSerumSignerPublicKey,
|
|
46
50
|
getUserAccountPublicKey,
|
|
47
51
|
getUserAccountPublicKeySync,
|
|
48
52
|
getUserStatsAccountPublicKey,
|
|
@@ -56,11 +60,11 @@ import { TxSender } from './tx/types';
|
|
|
56
60
|
import { wrapInTx } from './tx/utils';
|
|
57
61
|
import {
|
|
58
62
|
ONE,
|
|
59
|
-
|
|
63
|
+
QUOTE_SPOT_MARKET_INDEX,
|
|
60
64
|
ZERO,
|
|
61
65
|
} from './constants/numericConstants';
|
|
62
66
|
import { findDirectionToClose, positionIsAvailable } from './math/position';
|
|
63
|
-
import { getTokenAmount } from './math/
|
|
67
|
+
import { getTokenAmount } from './math/spotBalance';
|
|
64
68
|
import { DEFAULT_USER_NAME, encodeName } from './userName';
|
|
65
69
|
import { OraclePriceData } from './oracles/types';
|
|
66
70
|
import { ClearingHouseConfig } from './clearingHouseConfig';
|
|
@@ -69,9 +73,10 @@ import { WebSocketClearingHouseAccountSubscriber } from './accounts/webSocketCle
|
|
|
69
73
|
import { RetryTxSender } from './tx/retryTxSender';
|
|
70
74
|
import { ClearingHouseUser } from './clearingHouseUser';
|
|
71
75
|
import { ClearingHouseUserAccountSubscriptionConfig } from './clearingHouseUserConfig';
|
|
72
|
-
import {
|
|
73
|
-
import { WRAPPED_SOL_MINT } from './constants/
|
|
76
|
+
import { getMarketsAndOraclesForSubscription } from './config';
|
|
77
|
+
import { WRAPPED_SOL_MINT } from './constants/spotMarkets';
|
|
74
78
|
import { ClearingHouseUserStats } from './clearingHouseUserStats';
|
|
79
|
+
import { isSpotPositionAvailable } from './math/spotPosition';
|
|
75
80
|
|
|
76
81
|
/**
|
|
77
82
|
* # ClearingHouse
|
|
@@ -139,17 +144,21 @@ export class ClearingHouse {
|
|
|
139
144
|
});
|
|
140
145
|
}
|
|
141
146
|
|
|
142
|
-
let
|
|
143
|
-
let
|
|
147
|
+
let perpMarketIndexes = config.perpMarketIndexes;
|
|
148
|
+
let spotMarketIndexes = config.spotMarketIndexes;
|
|
144
149
|
let oracleInfos = config.oracleInfos;
|
|
145
150
|
if (config.env) {
|
|
146
151
|
const {
|
|
147
|
-
|
|
148
|
-
|
|
152
|
+
perpMarketIndexes: envPerpMarketIndexes,
|
|
153
|
+
spotMarketIndexes: envSpotMarketIndexes,
|
|
149
154
|
oracleInfos: envOralceInfos,
|
|
150
|
-
} =
|
|
151
|
-
|
|
152
|
-
|
|
155
|
+
} = getMarketsAndOraclesForSubscription(config.env);
|
|
156
|
+
perpMarketIndexes = perpMarketIndexes
|
|
157
|
+
? perpMarketIndexes
|
|
158
|
+
: envPerpMarketIndexes;
|
|
159
|
+
spotMarketIndexes = spotMarketIndexes
|
|
160
|
+
? spotMarketIndexes
|
|
161
|
+
: envSpotMarketIndexes;
|
|
153
162
|
oracleInfos = oracleInfos ? oracleInfos : envOralceInfos;
|
|
154
163
|
}
|
|
155
164
|
|
|
@@ -157,15 +166,15 @@ export class ClearingHouse {
|
|
|
157
166
|
this.accountSubscriber = new PollingClearingHouseAccountSubscriber(
|
|
158
167
|
this.program,
|
|
159
168
|
config.accountSubscription.accountLoader,
|
|
160
|
-
|
|
161
|
-
|
|
169
|
+
perpMarketIndexes ?? [],
|
|
170
|
+
spotMarketIndexes ?? [],
|
|
162
171
|
oracleInfos ?? []
|
|
163
172
|
);
|
|
164
173
|
} else {
|
|
165
174
|
this.accountSubscriber = new WebSocketClearingHouseAccountSubscriber(
|
|
166
175
|
this.program,
|
|
167
|
-
config.
|
|
168
|
-
config.
|
|
176
|
+
config.perpMarketIndexes ?? [],
|
|
177
|
+
config.spotMarketIndexes ?? [],
|
|
169
178
|
config.oracleInfos ?? []
|
|
170
179
|
);
|
|
171
180
|
}
|
|
@@ -276,25 +285,30 @@ export class ClearingHouse {
|
|
|
276
285
|
return this.accountSubscriber.getStateAccountAndSlot().data;
|
|
277
286
|
}
|
|
278
287
|
|
|
279
|
-
public
|
|
288
|
+
public getPerpMarketAccount(
|
|
289
|
+
marketIndex: BN | number
|
|
290
|
+
): PerpMarketAccount | undefined {
|
|
280
291
|
marketIndex = marketIndex instanceof BN ? marketIndex : new BN(marketIndex);
|
|
281
292
|
return this.accountSubscriber.getMarketAccountAndSlot(marketIndex)?.data;
|
|
282
293
|
}
|
|
283
294
|
|
|
284
|
-
public
|
|
295
|
+
public getPerpMarketAccounts(): PerpMarketAccount[] {
|
|
285
296
|
return this.accountSubscriber
|
|
286
297
|
.getMarketAccountsAndSlots()
|
|
287
298
|
.map((value) => value.data);
|
|
288
299
|
}
|
|
289
300
|
|
|
290
|
-
public
|
|
291
|
-
|
|
292
|
-
|
|
301
|
+
public getSpotMarketAccount(
|
|
302
|
+
marketIndex: BN | number
|
|
303
|
+
): SpotMarketAccount | undefined {
|
|
304
|
+
marketIndex = marketIndex instanceof BN ? marketIndex : new BN(marketIndex);
|
|
305
|
+
return this.accountSubscriber.getSpotMarketAccountAndSlot(marketIndex).data;
|
|
293
306
|
}
|
|
294
307
|
|
|
295
|
-
public
|
|
296
|
-
return this.accountSubscriber.
|
|
297
|
-
|
|
308
|
+
public getQuoteSpotMarketAccount(): SpotMarketAccount {
|
|
309
|
+
return this.accountSubscriber.getSpotMarketAccountAndSlot(
|
|
310
|
+
QUOTE_SPOT_MARKET_INDEX
|
|
311
|
+
).data;
|
|
298
312
|
}
|
|
299
313
|
|
|
300
314
|
public getOraclePriceDataAndSlot(
|
|
@@ -303,6 +317,18 @@ export class ClearingHouse {
|
|
|
303
317
|
return this.accountSubscriber.getOraclePriceDataAndSlot(oraclePublicKey);
|
|
304
318
|
}
|
|
305
319
|
|
|
320
|
+
public async getSerumV3FulfillmentConfig(
|
|
321
|
+
serumMarket: PublicKey
|
|
322
|
+
): Promise<SerumV3FulfillmentConfigAccount> {
|
|
323
|
+
const address = await getSerumFulfillmentConfigPublicKey(
|
|
324
|
+
this.program.programId,
|
|
325
|
+
serumMarket
|
|
326
|
+
);
|
|
327
|
+
return (await this.program.account.serumV3FulfillmentConfig.fetch(
|
|
328
|
+
address
|
|
329
|
+
)) as SerumV3FulfillmentConfigAccount;
|
|
330
|
+
}
|
|
331
|
+
|
|
306
332
|
/**
|
|
307
333
|
* Update the wallet to use for clearing house transactions and linked user account
|
|
308
334
|
* @param newWallet
|
|
@@ -433,6 +459,19 @@ export class ClearingHouse {
|
|
|
433
459
|
});
|
|
434
460
|
}
|
|
435
461
|
|
|
462
|
+
public async updateUserName(
|
|
463
|
+
name: string,
|
|
464
|
+
userId = 0
|
|
465
|
+
): Promise<TransactionSignature> {
|
|
466
|
+
const nameBuffer = encodeName(name);
|
|
467
|
+
return await this.program.rpc.updateUserName(userId, nameBuffer, {
|
|
468
|
+
accounts: {
|
|
469
|
+
user: await this.getUserAccountPublicKey(),
|
|
470
|
+
authority: this.wallet.publicKey,
|
|
471
|
+
},
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
|
|
436
475
|
public getUser(userId?: number): ClearingHouseUser {
|
|
437
476
|
userId = userId ?? this.activeUserId;
|
|
438
477
|
if (!this.users.has(userId)) {
|
|
@@ -476,29 +515,29 @@ export class ClearingHouse {
|
|
|
476
515
|
return this.getUser(userId).getUserAccountAndSlot();
|
|
477
516
|
}
|
|
478
517
|
|
|
479
|
-
public
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
bankBalance.bankIndex.eq(bankIndexBN)
|
|
518
|
+
public getSpotPosition(marketIndex: number | BN): SpotPosition | undefined {
|
|
519
|
+
const marketIndexBN =
|
|
520
|
+
marketIndex instanceof BN ? marketIndex : new BN(marketIndex);
|
|
521
|
+
return this.getUserAccount().spotPositions.find((spotPosition) =>
|
|
522
|
+
spotPosition.marketIndex.eq(marketIndexBN)
|
|
485
523
|
);
|
|
486
524
|
}
|
|
487
525
|
|
|
488
526
|
public getQuoteAssetTokenAmount(): BN {
|
|
489
|
-
const
|
|
490
|
-
const
|
|
527
|
+
const spotMarket = this.getSpotMarketAccount(QUOTE_SPOT_MARKET_INDEX);
|
|
528
|
+
const spotPosition = this.getSpotPosition(QUOTE_SPOT_MARKET_INDEX);
|
|
491
529
|
return getTokenAmount(
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
530
|
+
spotPosition.balance,
|
|
531
|
+
spotMarket,
|
|
532
|
+
spotPosition.balanceType
|
|
495
533
|
);
|
|
496
534
|
}
|
|
497
535
|
|
|
498
536
|
getRemainingAccounts(params: {
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
537
|
+
writablePerpMarketIndex?: BN;
|
|
538
|
+
writableSpotMarketIndex?: BN;
|
|
539
|
+
readablePerpMarketIndex?: BN;
|
|
540
|
+
readableSpotMarketIndex?: BN;
|
|
502
541
|
}): AccountMeta[] {
|
|
503
542
|
const userAccountAndSlot = this.getUserAccountAndSlot();
|
|
504
543
|
if (!userAccountAndSlot) {
|
|
@@ -510,14 +549,14 @@ export class ClearingHouse {
|
|
|
510
549
|
userAccountAndSlot;
|
|
511
550
|
|
|
512
551
|
const oracleAccountMap = new Map<string, AccountMeta>();
|
|
513
|
-
const
|
|
514
|
-
const
|
|
552
|
+
const spotMarketAccountMap = new Map<number, AccountMeta>();
|
|
553
|
+
const perpMarketAccountMap = new Map<number, AccountMeta>();
|
|
515
554
|
for (const [marketIndexNum, slot] of this.marketLastSlotCache.entries()) {
|
|
516
555
|
// if cache has more recent slot than user positions account slot, add market to remaining accounts
|
|
517
556
|
// otherwise remove from slot
|
|
518
557
|
if (slot > lastUserPositionsSlot) {
|
|
519
|
-
const marketAccount = this.
|
|
520
|
-
|
|
558
|
+
const marketAccount = this.getPerpMarketAccount(marketIndexNum);
|
|
559
|
+
perpMarketAccountMap.set(marketIndexNum, {
|
|
521
560
|
pubkey: marketAccount.pubkey,
|
|
522
561
|
isSigner: false,
|
|
523
562
|
isWritable: false,
|
|
@@ -532,11 +571,11 @@ export class ClearingHouse {
|
|
|
532
571
|
}
|
|
533
572
|
}
|
|
534
573
|
|
|
535
|
-
for (const position of userAccount.
|
|
574
|
+
for (const position of userAccount.perpPositions) {
|
|
536
575
|
if (!positionIsAvailable(position)) {
|
|
537
576
|
const marketIndexNum = position.marketIndex.toNumber();
|
|
538
|
-
const marketAccount = this.
|
|
539
|
-
|
|
577
|
+
const marketAccount = this.getPerpMarketAccount(marketIndexNum);
|
|
578
|
+
perpMarketAccountMap.set(marketIndexNum, {
|
|
540
579
|
pubkey: marketAccount.pubkey,
|
|
541
580
|
isSigner: false,
|
|
542
581
|
isWritable: false,
|
|
@@ -549,11 +588,11 @@ export class ClearingHouse {
|
|
|
549
588
|
}
|
|
550
589
|
}
|
|
551
590
|
|
|
552
|
-
if (params.
|
|
553
|
-
const marketAccount = this.
|
|
554
|
-
params.
|
|
591
|
+
if (params.readablePerpMarketIndex) {
|
|
592
|
+
const marketAccount = this.getPerpMarketAccount(
|
|
593
|
+
params.readablePerpMarketIndex.toNumber()
|
|
555
594
|
);
|
|
556
|
-
|
|
595
|
+
perpMarketAccountMap.set(params.readablePerpMarketIndex.toNumber(), {
|
|
557
596
|
pubkey: marketAccount.pubkey,
|
|
558
597
|
isSigner: false,
|
|
559
598
|
isWritable: true,
|
|
@@ -565,11 +604,11 @@ export class ClearingHouse {
|
|
|
565
604
|
});
|
|
566
605
|
}
|
|
567
606
|
|
|
568
|
-
if (params.
|
|
569
|
-
const marketAccount = this.
|
|
570
|
-
params.
|
|
607
|
+
if (params.writablePerpMarketIndex) {
|
|
608
|
+
const marketAccount = this.getPerpMarketAccount(
|
|
609
|
+
params.writablePerpMarketIndex.toNumber()
|
|
571
610
|
);
|
|
572
|
-
|
|
611
|
+
perpMarketAccountMap.set(params.writablePerpMarketIndex.toNumber(), {
|
|
573
612
|
pubkey: marketAccount.pubkey,
|
|
574
613
|
isSigner: false,
|
|
575
614
|
isWritable: true,
|
|
@@ -581,17 +620,19 @@ export class ClearingHouse {
|
|
|
581
620
|
});
|
|
582
621
|
}
|
|
583
622
|
|
|
584
|
-
for (const
|
|
585
|
-
if (!
|
|
586
|
-
const
|
|
587
|
-
|
|
588
|
-
|
|
623
|
+
for (const spotPosition of userAccount.spotPositions) {
|
|
624
|
+
if (!isSpotPositionAvailable(spotPosition)) {
|
|
625
|
+
const spotMarketAccount = this.getSpotMarketAccount(
|
|
626
|
+
spotPosition.marketIndex
|
|
627
|
+
);
|
|
628
|
+
spotMarketAccountMap.set(spotPosition.marketIndex.toNumber(), {
|
|
629
|
+
pubkey: spotMarketAccount.pubkey,
|
|
589
630
|
isSigner: false,
|
|
590
631
|
isWritable: false,
|
|
591
632
|
});
|
|
592
|
-
if (!
|
|
593
|
-
oracleAccountMap.set(
|
|
594
|
-
pubkey:
|
|
633
|
+
if (!spotMarketAccount.marketIndex.eq(ZERO)) {
|
|
634
|
+
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
635
|
+
pubkey: spotMarketAccount.oracle,
|
|
595
636
|
isSigner: false,
|
|
596
637
|
isWritable: false,
|
|
597
638
|
});
|
|
@@ -599,16 +640,36 @@ export class ClearingHouse {
|
|
|
599
640
|
}
|
|
600
641
|
}
|
|
601
642
|
|
|
602
|
-
if (params.
|
|
603
|
-
const
|
|
604
|
-
|
|
605
|
-
|
|
643
|
+
if (params.readableSpotMarketIndex) {
|
|
644
|
+
const spotMarketAccount = this.getSpotMarketAccount(
|
|
645
|
+
params.readableSpotMarketIndex
|
|
646
|
+
);
|
|
647
|
+
spotMarketAccountMap.set(params.readableSpotMarketIndex.toNumber(), {
|
|
648
|
+
pubkey: spotMarketAccount.pubkey,
|
|
649
|
+
isSigner: false,
|
|
650
|
+
isWritable: false,
|
|
651
|
+
});
|
|
652
|
+
if (!spotMarketAccount.marketIndex.eq(ZERO)) {
|
|
653
|
+
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
654
|
+
pubkey: spotMarketAccount.oracle,
|
|
655
|
+
isSigner: false,
|
|
656
|
+
isWritable: false,
|
|
657
|
+
});
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
if (params.writableSpotMarketIndex) {
|
|
662
|
+
const spotMarketAccount = this.getSpotMarketAccount(
|
|
663
|
+
params.writableSpotMarketIndex
|
|
664
|
+
);
|
|
665
|
+
spotMarketAccountMap.set(params.writableSpotMarketIndex.toNumber(), {
|
|
666
|
+
pubkey: spotMarketAccount.pubkey,
|
|
606
667
|
isSigner: false,
|
|
607
668
|
isWritable: true,
|
|
608
669
|
});
|
|
609
|
-
if (!
|
|
610
|
-
oracleAccountMap.set(
|
|
611
|
-
pubkey:
|
|
670
|
+
if (!spotMarketAccount.marketIndex.eq(ZERO)) {
|
|
671
|
+
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
672
|
+
pubkey: spotMarketAccount.oracle,
|
|
612
673
|
isSigner: false,
|
|
613
674
|
isWritable: false,
|
|
614
675
|
});
|
|
@@ -617,8 +678,8 @@ export class ClearingHouse {
|
|
|
617
678
|
|
|
618
679
|
return [
|
|
619
680
|
...oracleAccountMap.values(),
|
|
620
|
-
...
|
|
621
|
-
...
|
|
681
|
+
...spotMarketAccountMap.values(),
|
|
682
|
+
...perpMarketAccountMap.values(),
|
|
622
683
|
];
|
|
623
684
|
}
|
|
624
685
|
|
|
@@ -637,7 +698,7 @@ export class ClearingHouse {
|
|
|
637
698
|
|
|
638
699
|
public async deposit(
|
|
639
700
|
amount: BN,
|
|
640
|
-
|
|
701
|
+
marketIndex: BN,
|
|
641
702
|
collateralAccountPublicKey: PublicKey,
|
|
642
703
|
userId?: number,
|
|
643
704
|
reduceOnly = false
|
|
@@ -645,14 +706,14 @@ export class ClearingHouse {
|
|
|
645
706
|
const tx = new Transaction();
|
|
646
707
|
const additionalSigners: Array<Signer> = [];
|
|
647
708
|
|
|
648
|
-
const
|
|
709
|
+
const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
|
|
649
710
|
|
|
650
|
-
const
|
|
711
|
+
const isSolMarket = spotMarketAccount.mint.equals(WRAPPED_SOL_MINT);
|
|
651
712
|
|
|
652
713
|
const authority = this.wallet.publicKey;
|
|
653
714
|
|
|
654
715
|
const createWSOLTokenAccount =
|
|
655
|
-
|
|
716
|
+
isSolMarket && collateralAccountPublicKey.equals(authority);
|
|
656
717
|
|
|
657
718
|
if (createWSOLTokenAccount) {
|
|
658
719
|
const { ixs, signers, pubkey } =
|
|
@@ -669,7 +730,7 @@ export class ClearingHouse {
|
|
|
669
730
|
|
|
670
731
|
const depositCollateralIx = await this.getDepositInstruction(
|
|
671
732
|
amount,
|
|
672
|
-
|
|
733
|
+
marketIndex,
|
|
673
734
|
collateralAccountPublicKey,
|
|
674
735
|
userId,
|
|
675
736
|
reduceOnly,
|
|
@@ -701,7 +762,7 @@ export class ClearingHouse {
|
|
|
701
762
|
|
|
702
763
|
async getDepositInstruction(
|
|
703
764
|
amount: BN,
|
|
704
|
-
|
|
765
|
+
marketIndex: BN,
|
|
705
766
|
userTokenAccount: PublicKey,
|
|
706
767
|
userId?: number,
|
|
707
768
|
reduceOnly = false,
|
|
@@ -718,35 +779,35 @@ export class ClearingHouse {
|
|
|
718
779
|
let remainingAccounts = [];
|
|
719
780
|
if (userInitialized) {
|
|
720
781
|
remainingAccounts = this.getRemainingAccounts({
|
|
721
|
-
|
|
782
|
+
writableSpotMarketIndex: marketIndex,
|
|
722
783
|
});
|
|
723
784
|
} else {
|
|
724
|
-
const
|
|
725
|
-
if (!
|
|
785
|
+
const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
|
|
786
|
+
if (!spotMarketAccount.oracle.equals(PublicKey.default)) {
|
|
726
787
|
remainingAccounts.push({
|
|
727
|
-
pubkey:
|
|
788
|
+
pubkey: spotMarketAccount.oracle,
|
|
728
789
|
isSigner: false,
|
|
729
790
|
isWritable: false,
|
|
730
791
|
});
|
|
731
792
|
}
|
|
732
793
|
remainingAccounts.push({
|
|
733
|
-
pubkey:
|
|
794
|
+
pubkey: spotMarketAccount.pubkey,
|
|
734
795
|
isSigner: false,
|
|
735
796
|
isWritable: true,
|
|
736
797
|
});
|
|
737
798
|
}
|
|
738
799
|
|
|
739
|
-
const
|
|
800
|
+
const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
|
|
740
801
|
|
|
741
802
|
return await this.program.instruction.deposit(
|
|
742
|
-
|
|
803
|
+
marketIndex,
|
|
743
804
|
amount,
|
|
744
805
|
reduceOnly,
|
|
745
806
|
{
|
|
746
807
|
accounts: {
|
|
747
808
|
state: await this.getStatePublicKey(),
|
|
748
|
-
|
|
749
|
-
|
|
809
|
+
spotMarket: spotMarketAccount.pubkey,
|
|
810
|
+
spotMarketVault: spotMarketAccount.vault,
|
|
750
811
|
user: userAccountPublicKey,
|
|
751
812
|
userStats: this.getUserStatsAccountPublicKey(),
|
|
752
813
|
userTokenAccount: userTokenAccount,
|
|
@@ -769,7 +830,7 @@ export class ClearingHouse {
|
|
|
769
830
|
}
|
|
770
831
|
|
|
771
832
|
private async getSolWithdrawalIxs(
|
|
772
|
-
|
|
833
|
+
marketIndex: BN,
|
|
773
834
|
amount: BN
|
|
774
835
|
): Promise<{
|
|
775
836
|
ixs: anchor.web3.TransactionInstruction[];
|
|
@@ -801,7 +862,7 @@ export class ClearingHouse {
|
|
|
801
862
|
|
|
802
863
|
const withdrawIx = await this.getWithdrawIx(
|
|
803
864
|
amount,
|
|
804
|
-
|
|
865
|
+
marketIndex,
|
|
805
866
|
pubkey,
|
|
806
867
|
true
|
|
807
868
|
);
|
|
@@ -868,7 +929,7 @@ export class ClearingHouse {
|
|
|
868
929
|
* Creates the Clearing House User account for a user, and deposits some initial collateral
|
|
869
930
|
* @param amount
|
|
870
931
|
* @param userTokenAccount
|
|
871
|
-
* @param
|
|
932
|
+
* @param marketIndex
|
|
872
933
|
* @param userId
|
|
873
934
|
* @param name
|
|
874
935
|
* @param fromUserId
|
|
@@ -877,7 +938,7 @@ export class ClearingHouse {
|
|
|
877
938
|
public async initializeUserAccountAndDepositCollateral(
|
|
878
939
|
amount: BN,
|
|
879
940
|
userTokenAccount: PublicKey,
|
|
880
|
-
|
|
941
|
+
marketIndex = new BN(0),
|
|
881
942
|
userId = 0,
|
|
882
943
|
name = DEFAULT_USER_NAME,
|
|
883
944
|
fromUserId?: number,
|
|
@@ -888,16 +949,16 @@ export class ClearingHouse {
|
|
|
888
949
|
|
|
889
950
|
const additionalSigners: Array<Signer> = [];
|
|
890
951
|
|
|
891
|
-
const
|
|
952
|
+
const spotMarket = this.getSpotMarketAccount(marketIndex);
|
|
892
953
|
|
|
893
|
-
const
|
|
954
|
+
const isSolMarket = spotMarket.mint.equals(WRAPPED_SOL_MINT);
|
|
894
955
|
|
|
895
956
|
const tx = new Transaction();
|
|
896
957
|
|
|
897
958
|
const authority = this.wallet.publicKey;
|
|
898
959
|
|
|
899
960
|
const createWSOLTokenAccount =
|
|
900
|
-
|
|
961
|
+
isSolMarket && userTokenAccount.equals(authority);
|
|
901
962
|
|
|
902
963
|
if (createWSOLTokenAccount) {
|
|
903
964
|
const {
|
|
@@ -917,10 +978,15 @@ export class ClearingHouse {
|
|
|
917
978
|
|
|
918
979
|
const depositCollateralIx =
|
|
919
980
|
fromUserId != null
|
|
920
|
-
? await this.getTransferDepositIx(
|
|
981
|
+
? await this.getTransferDepositIx(
|
|
982
|
+
amount,
|
|
983
|
+
marketIndex,
|
|
984
|
+
fromUserId,
|
|
985
|
+
userId
|
|
986
|
+
)
|
|
921
987
|
: await this.getDepositInstruction(
|
|
922
988
|
amount,
|
|
923
|
-
|
|
989
|
+
marketIndex,
|
|
924
990
|
userTokenAccount,
|
|
925
991
|
userId,
|
|
926
992
|
false,
|
|
@@ -957,7 +1023,7 @@ export class ClearingHouse {
|
|
|
957
1023
|
public async initializeUserAccountForDevnet(
|
|
958
1024
|
userId = 0,
|
|
959
1025
|
name = DEFAULT_USER_NAME,
|
|
960
|
-
|
|
1026
|
+
marketIndex: BN,
|
|
961
1027
|
tokenFaucet: TokenFaucet,
|
|
962
1028
|
amount: BN,
|
|
963
1029
|
referrerInfo?: ReferrerInfo
|
|
@@ -973,7 +1039,7 @@ export class ClearingHouse {
|
|
|
973
1039
|
|
|
974
1040
|
const depositCollateralIx = await this.getDepositInstruction(
|
|
975
1041
|
amount,
|
|
976
|
-
|
|
1042
|
+
marketIndex,
|
|
977
1043
|
associateTokenPublicKey,
|
|
978
1044
|
userId,
|
|
979
1045
|
false,
|
|
@@ -994,21 +1060,21 @@ export class ClearingHouse {
|
|
|
994
1060
|
|
|
995
1061
|
public async withdraw(
|
|
996
1062
|
amount: BN,
|
|
997
|
-
|
|
1063
|
+
marketIndex: BN,
|
|
998
1064
|
userTokenAccount: PublicKey,
|
|
999
1065
|
reduceOnly = false
|
|
1000
1066
|
): Promise<TransactionSignature> {
|
|
1001
1067
|
const tx = new Transaction();
|
|
1002
1068
|
const additionalSigners: Array<Signer> = [];
|
|
1003
1069
|
|
|
1004
|
-
const
|
|
1070
|
+
const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
|
|
1005
1071
|
|
|
1006
|
-
const
|
|
1072
|
+
const isSolMarket = spotMarketAccount.mint.equals(WRAPPED_SOL_MINT);
|
|
1007
1073
|
|
|
1008
1074
|
const authority = this.wallet.publicKey;
|
|
1009
1075
|
|
|
1010
1076
|
const createWSOLTokenAccount =
|
|
1011
|
-
|
|
1077
|
+
isSolMarket && userTokenAccount.equals(authority);
|
|
1012
1078
|
|
|
1013
1079
|
if (createWSOLTokenAccount) {
|
|
1014
1080
|
const { ixs, signers, pubkey } =
|
|
@@ -1025,7 +1091,7 @@ export class ClearingHouse {
|
|
|
1025
1091
|
|
|
1026
1092
|
const withdrawCollateral = await this.getWithdrawIx(
|
|
1027
1093
|
amount,
|
|
1028
|
-
|
|
1094
|
+
spotMarketAccount.marketIndex,
|
|
1029
1095
|
userTokenAccount,
|
|
1030
1096
|
reduceOnly
|
|
1031
1097
|
);
|
|
@@ -1055,27 +1121,27 @@ export class ClearingHouse {
|
|
|
1055
1121
|
|
|
1056
1122
|
public async getWithdrawIx(
|
|
1057
1123
|
amount: BN,
|
|
1058
|
-
|
|
1124
|
+
marketIndex: BN,
|
|
1059
1125
|
userTokenAccount: PublicKey,
|
|
1060
1126
|
reduceOnly = false
|
|
1061
1127
|
): Promise<TransactionInstruction> {
|
|
1062
1128
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
1063
1129
|
|
|
1064
1130
|
const remainingAccounts = this.getRemainingAccounts({
|
|
1065
|
-
|
|
1131
|
+
writableSpotMarketIndex: marketIndex,
|
|
1066
1132
|
});
|
|
1067
1133
|
|
|
1068
|
-
const
|
|
1134
|
+
const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
|
|
1069
1135
|
|
|
1070
1136
|
return await this.program.instruction.withdraw(
|
|
1071
|
-
|
|
1137
|
+
marketIndex,
|
|
1072
1138
|
amount,
|
|
1073
1139
|
reduceOnly,
|
|
1074
1140
|
{
|
|
1075
1141
|
accounts: {
|
|
1076
1142
|
state: await this.getStatePublicKey(),
|
|
1077
|
-
|
|
1078
|
-
|
|
1143
|
+
spotMarket: spotMarketAccount.pubkey,
|
|
1144
|
+
spotMarketVault: spotMarketAccount.vault,
|
|
1079
1145
|
clearingHouseSigner: this.getSignerPublicKey(),
|
|
1080
1146
|
user: userAccountPublicKey,
|
|
1081
1147
|
userStats: this.getUserStatsAccountPublicKey(),
|
|
@@ -1090,13 +1156,18 @@ export class ClearingHouse {
|
|
|
1090
1156
|
|
|
1091
1157
|
public async transferDeposit(
|
|
1092
1158
|
amount: BN,
|
|
1093
|
-
|
|
1159
|
+
marketIndex: BN,
|
|
1094
1160
|
fromUserId: number,
|
|
1095
1161
|
toUserId: number
|
|
1096
1162
|
): Promise<TransactionSignature> {
|
|
1097
1163
|
const { txSig } = await this.txSender.send(
|
|
1098
1164
|
wrapInTx(
|
|
1099
|
-
await this.getTransferDepositIx(
|
|
1165
|
+
await this.getTransferDepositIx(
|
|
1166
|
+
amount,
|
|
1167
|
+
marketIndex,
|
|
1168
|
+
fromUserId,
|
|
1169
|
+
toUserId
|
|
1170
|
+
)
|
|
1100
1171
|
),
|
|
1101
1172
|
[],
|
|
1102
1173
|
this.opts
|
|
@@ -1106,7 +1177,7 @@ export class ClearingHouse {
|
|
|
1106
1177
|
|
|
1107
1178
|
public async getTransferDepositIx(
|
|
1108
1179
|
amount: BN,
|
|
1109
|
-
|
|
1180
|
+
marketIndex: BN,
|
|
1110
1181
|
fromUserId: number,
|
|
1111
1182
|
toUserId: number
|
|
1112
1183
|
): Promise<TransactionInstruction> {
|
|
@@ -1122,10 +1193,10 @@ export class ClearingHouse {
|
|
|
1122
1193
|
);
|
|
1123
1194
|
|
|
1124
1195
|
const remainingAccounts = this.getRemainingAccounts({
|
|
1125
|
-
|
|
1196
|
+
writableSpotMarketIndex: marketIndex,
|
|
1126
1197
|
});
|
|
1127
1198
|
|
|
1128
|
-
return await this.program.instruction.transferDeposit(
|
|
1199
|
+
return await this.program.instruction.transferDeposit(marketIndex, amount, {
|
|
1129
1200
|
accounts: {
|
|
1130
1201
|
authority: this.wallet.publicKey,
|
|
1131
1202
|
fromUser,
|
|
@@ -1137,24 +1208,24 @@ export class ClearingHouse {
|
|
|
1137
1208
|
});
|
|
1138
1209
|
}
|
|
1139
1210
|
|
|
1140
|
-
public async
|
|
1141
|
-
|
|
1211
|
+
public async updateSpotMarketCumulativeInterest(
|
|
1212
|
+
marketIndex: BN
|
|
1142
1213
|
): Promise<TransactionSignature> {
|
|
1143
1214
|
const { txSig } = await this.txSender.send(
|
|
1144
|
-
wrapInTx(await this.
|
|
1215
|
+
wrapInTx(await this.updateSpotMarketCumulativeInterestIx(marketIndex)),
|
|
1145
1216
|
[],
|
|
1146
1217
|
this.opts
|
|
1147
1218
|
);
|
|
1148
1219
|
return txSig;
|
|
1149
1220
|
}
|
|
1150
1221
|
|
|
1151
|
-
public async
|
|
1152
|
-
|
|
1222
|
+
public async updateSpotMarketCumulativeInterestIx(
|
|
1223
|
+
marketIndex: BN
|
|
1153
1224
|
): Promise<TransactionInstruction> {
|
|
1154
|
-
const
|
|
1155
|
-
return await this.program.instruction.
|
|
1225
|
+
const spotMarket = this.getSpotMarketAccount(marketIndex);
|
|
1226
|
+
return await this.program.instruction.updateSpotMarketCumulativeInterest({
|
|
1156
1227
|
accounts: {
|
|
1157
|
-
|
|
1228
|
+
spotMarket: spotMarket.pubkey,
|
|
1158
1229
|
},
|
|
1159
1230
|
});
|
|
1160
1231
|
}
|
|
@@ -1178,7 +1249,7 @@ export class ClearingHouse {
|
|
|
1178
1249
|
const settleeUserAccount = (await this.program.account.user.fetch(
|
|
1179
1250
|
settleeUserAccountPublicKey
|
|
1180
1251
|
)) as UserAccount;
|
|
1181
|
-
const userPositions = settleeUserAccount.
|
|
1252
|
+
const userPositions = settleeUserAccount.perpPositions;
|
|
1182
1253
|
const remainingAccounts = [];
|
|
1183
1254
|
|
|
1184
1255
|
let foundMarket = false;
|
|
@@ -1234,15 +1305,15 @@ export class ClearingHouse {
|
|
|
1234
1305
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
1235
1306
|
|
|
1236
1307
|
const remainingAccounts = this.getRemainingAccounts({
|
|
1237
|
-
|
|
1308
|
+
writablePerpMarketIndex: marketIndex,
|
|
1238
1309
|
});
|
|
1239
1310
|
|
|
1240
1311
|
if (sharesToBurn == undefined) {
|
|
1241
1312
|
const userAccount = this.getUserAccount();
|
|
1242
|
-
const
|
|
1313
|
+
const perpPosition = userAccount.perpPositions.filter((position) =>
|
|
1243
1314
|
position.marketIndex.eq(marketIndex)
|
|
1244
1315
|
)[0];
|
|
1245
|
-
sharesToBurn =
|
|
1316
|
+
sharesToBurn = perpPosition.lpShares;
|
|
1246
1317
|
console.log('burning lp shares:', sharesToBurn.toString());
|
|
1247
1318
|
}
|
|
1248
1319
|
|
|
@@ -1275,7 +1346,7 @@ export class ClearingHouse {
|
|
|
1275
1346
|
): Promise<TransactionInstruction> {
|
|
1276
1347
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
1277
1348
|
const remainingAccounts = this.getRemainingAccounts({
|
|
1278
|
-
|
|
1349
|
+
writablePerpMarketIndex: marketIndex,
|
|
1279
1350
|
});
|
|
1280
1351
|
|
|
1281
1352
|
return this.program.instruction.addLiquidity(amount, marketIndex, {
|
|
@@ -1303,6 +1374,60 @@ export class ClearingHouse {
|
|
|
1303
1374
|
});
|
|
1304
1375
|
}
|
|
1305
1376
|
|
|
1377
|
+
public async sendSignedTx(tx: Transaction): Promise<TransactionSignature> {
|
|
1378
|
+
const { txSig } = await this.txSender.send(tx, undefined, this.opts, true);
|
|
1379
|
+
|
|
1380
|
+
return txSig;
|
|
1381
|
+
}
|
|
1382
|
+
|
|
1383
|
+
/**
|
|
1384
|
+
* Sends a market order and returns a signed tx which can fill the order against the vamm, which the caller can use to fill their own order if required.
|
|
1385
|
+
* @param orderParams
|
|
1386
|
+
* @param userAccountPublicKey
|
|
1387
|
+
* @param userAccount
|
|
1388
|
+
* @returns
|
|
1389
|
+
*/
|
|
1390
|
+
public async sendMarketOrderAndGetSignedFillTx(
|
|
1391
|
+
orderParams: OptionalOrderParams,
|
|
1392
|
+
userAccountPublicKey: PublicKey,
|
|
1393
|
+
userAccount: UserAccount
|
|
1394
|
+
): Promise<{ txSig: TransactionSignature; signedFillTx: Transaction }> {
|
|
1395
|
+
const marketIndex = orderParams.marketIndex;
|
|
1396
|
+
const orderId = userAccount.nextOrderId;
|
|
1397
|
+
|
|
1398
|
+
const marketOrderTx = wrapInTx(await this.getPlaceOrderIx(orderParams));
|
|
1399
|
+
const fillTx = wrapInTx(
|
|
1400
|
+
await this.getFillOrderIx(userAccountPublicKey, userAccount, {
|
|
1401
|
+
orderId,
|
|
1402
|
+
marketIndex,
|
|
1403
|
+
})
|
|
1404
|
+
);
|
|
1405
|
+
|
|
1406
|
+
// Apply the latest blockhash to the txs so that we can sign before sending them
|
|
1407
|
+
const currentBlockHash = (
|
|
1408
|
+
await this.connection.getLatestBlockhash('finalized')
|
|
1409
|
+
).blockhash;
|
|
1410
|
+
marketOrderTx.recentBlockhash = currentBlockHash;
|
|
1411
|
+
fillTx.recentBlockhash = currentBlockHash;
|
|
1412
|
+
|
|
1413
|
+
marketOrderTx.feePayer = userAccount.authority;
|
|
1414
|
+
fillTx.feePayer = userAccount.authority;
|
|
1415
|
+
|
|
1416
|
+
const [signedMarketOrderTx, signedFillTx] =
|
|
1417
|
+
await this.provider.wallet.signAllTransactions([marketOrderTx, fillTx]);
|
|
1418
|
+
|
|
1419
|
+
const { txSig, slot } = await this.txSender.send(
|
|
1420
|
+
signedMarketOrderTx,
|
|
1421
|
+
[],
|
|
1422
|
+
this.opts,
|
|
1423
|
+
true
|
|
1424
|
+
);
|
|
1425
|
+
|
|
1426
|
+
this.marketLastSlotCache.set(orderParams.marketIndex.toNumber(), slot);
|
|
1427
|
+
|
|
1428
|
+
return { txSig, signedFillTx };
|
|
1429
|
+
}
|
|
1430
|
+
|
|
1306
1431
|
public async placeOrder(
|
|
1307
1432
|
orderParams: OptionalOrderParams
|
|
1308
1433
|
): Promise<TransactionSignature> {
|
|
@@ -1315,18 +1440,23 @@ export class ClearingHouse {
|
|
|
1315
1440
|
return txSig;
|
|
1316
1441
|
}
|
|
1317
1442
|
|
|
1318
|
-
getOrderParams(
|
|
1319
|
-
|
|
1443
|
+
getOrderParams(
|
|
1444
|
+
optionalOrderParams: OptionalOrderParams,
|
|
1445
|
+
marketType: MarketType
|
|
1446
|
+
): OrderParams {
|
|
1447
|
+
return Object.assign({}, DefaultOrderParams, optionalOrderParams, {
|
|
1448
|
+
marketType,
|
|
1449
|
+
});
|
|
1320
1450
|
}
|
|
1321
1451
|
|
|
1322
1452
|
public async getPlaceOrderIx(
|
|
1323
1453
|
orderParams: OptionalOrderParams
|
|
1324
1454
|
): Promise<TransactionInstruction> {
|
|
1325
|
-
orderParams = this.getOrderParams(orderParams);
|
|
1455
|
+
orderParams = this.getOrderParams(orderParams, MarketType.PERP);
|
|
1326
1456
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
1327
1457
|
|
|
1328
1458
|
const remainingAccounts = this.getRemainingAccounts({
|
|
1329
|
-
|
|
1459
|
+
readablePerpMarketIndex: orderParams.marketIndex,
|
|
1330
1460
|
});
|
|
1331
1461
|
|
|
1332
1462
|
return await this.program.instruction.placeOrder(orderParams, {
|
|
@@ -1359,7 +1489,7 @@ export class ClearingHouse {
|
|
|
1359
1489
|
const oracleAccountInfos = [];
|
|
1360
1490
|
for (const marketIndex of marketIndexes) {
|
|
1361
1491
|
if (!marketIndex.eq(new BN(100))) {
|
|
1362
|
-
const market = this.
|
|
1492
|
+
const market = this.getPerpMarketAccount(marketIndex);
|
|
1363
1493
|
marketAccountInfos.push({
|
|
1364
1494
|
pubkey: market.pubkey,
|
|
1365
1495
|
isWritable: true,
|
|
@@ -1383,6 +1513,54 @@ export class ClearingHouse {
|
|
|
1383
1513
|
});
|
|
1384
1514
|
}
|
|
1385
1515
|
|
|
1516
|
+
public async settleExpiredMarket(
|
|
1517
|
+
marketIndex: BN
|
|
1518
|
+
): Promise<TransactionSignature> {
|
|
1519
|
+
const { txSig } = await this.txSender.send(
|
|
1520
|
+
wrapInTx(await this.getSettleExpiredMarketIx(marketIndex)),
|
|
1521
|
+
[],
|
|
1522
|
+
this.opts
|
|
1523
|
+
);
|
|
1524
|
+
return txSig;
|
|
1525
|
+
}
|
|
1526
|
+
|
|
1527
|
+
public async getSettleExpiredMarketIx(
|
|
1528
|
+
marketIndex: BN
|
|
1529
|
+
): Promise<TransactionInstruction> {
|
|
1530
|
+
const marketAccountInfos = [];
|
|
1531
|
+
const oracleAccountInfos = [];
|
|
1532
|
+
const spotMarketAccountInfos = [];
|
|
1533
|
+
const market = this.getPerpMarketAccount(marketIndex);
|
|
1534
|
+
marketAccountInfos.push({
|
|
1535
|
+
pubkey: market.pubkey,
|
|
1536
|
+
isWritable: true,
|
|
1537
|
+
isSigner: false,
|
|
1538
|
+
});
|
|
1539
|
+
oracleAccountInfos.push({
|
|
1540
|
+
pubkey: market.amm.oracle,
|
|
1541
|
+
isWritable: false,
|
|
1542
|
+
isSigner: false,
|
|
1543
|
+
});
|
|
1544
|
+
|
|
1545
|
+
spotMarketAccountInfos.push({
|
|
1546
|
+
pubkey: this.getSpotMarketAccount(QUOTE_SPOT_MARKET_INDEX).pubkey,
|
|
1547
|
+
isSigner: false,
|
|
1548
|
+
isWritable: true,
|
|
1549
|
+
});
|
|
1550
|
+
|
|
1551
|
+
const remainingAccounts = oracleAccountInfos
|
|
1552
|
+
.concat(spotMarketAccountInfos)
|
|
1553
|
+
.concat(marketAccountInfos);
|
|
1554
|
+
|
|
1555
|
+
return await this.program.instruction.settleExpiredMarket(marketIndex, {
|
|
1556
|
+
accounts: {
|
|
1557
|
+
state: await this.getStatePublicKey(),
|
|
1558
|
+
authority: this.wallet.publicKey,
|
|
1559
|
+
},
|
|
1560
|
+
remainingAccounts,
|
|
1561
|
+
});
|
|
1562
|
+
}
|
|
1563
|
+
|
|
1386
1564
|
public async cancelOrder(orderId?: BN): Promise<TransactionSignature> {
|
|
1387
1565
|
const { txSig } = await this.txSender.send(
|
|
1388
1566
|
wrapInTx(await this.getCancelOrderIx(orderId)),
|
|
@@ -1424,7 +1602,7 @@ export class ClearingHouse {
|
|
|
1424
1602
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
1425
1603
|
|
|
1426
1604
|
const order = this.getOrderByUserId(userOrderId);
|
|
1427
|
-
const oracle = this.
|
|
1605
|
+
const oracle = this.getPerpMarketAccount(order.marketIndex).amm.oracle;
|
|
1428
1606
|
|
|
1429
1607
|
const remainingAccounts = this.getRemainingAccounts({});
|
|
1430
1608
|
|
|
@@ -1465,7 +1643,7 @@ export class ClearingHouse {
|
|
|
1465
1643
|
public async getFillOrderIx(
|
|
1466
1644
|
userAccountPublicKey: PublicKey,
|
|
1467
1645
|
userAccount: UserAccount,
|
|
1468
|
-
order: Order,
|
|
1646
|
+
order: Pick<Order, 'marketIndex' | 'orderId'>,
|
|
1469
1647
|
makerInfo?: MakerInfo,
|
|
1470
1648
|
referrerInfo?: ReferrerInfo
|
|
1471
1649
|
): Promise<TransactionInstruction> {
|
|
@@ -1482,24 +1660,26 @@ export class ClearingHouse {
|
|
|
1482
1660
|
: userAccount.orders.find((order) =>
|
|
1483
1661
|
order.orderId.eq(userAccount.nextOrderId.sub(ONE))
|
|
1484
1662
|
).marketIndex;
|
|
1485
|
-
const marketAccount = this.
|
|
1663
|
+
const marketAccount = this.getPerpMarketAccount(marketIndex);
|
|
1486
1664
|
|
|
1487
1665
|
const oracleAccountMap = new Map<string, AccountMeta>();
|
|
1488
|
-
const
|
|
1489
|
-
const
|
|
1666
|
+
const spotMarketAccountMap = new Map<number, AccountMeta>();
|
|
1667
|
+
const perpMarketAccountMap = new Map<number, AccountMeta>();
|
|
1490
1668
|
|
|
1491
|
-
for (const
|
|
1492
|
-
if (!
|
|
1493
|
-
const
|
|
1494
|
-
|
|
1495
|
-
|
|
1669
|
+
for (const spotPosition of userAccount.spotPositions) {
|
|
1670
|
+
if (!isSpotPositionAvailable(spotPosition)) {
|
|
1671
|
+
const spotMarketAccount = this.getSpotMarketAccount(
|
|
1672
|
+
spotPosition.marketIndex
|
|
1673
|
+
);
|
|
1674
|
+
spotMarketAccountMap.set(spotPosition.marketIndex.toNumber(), {
|
|
1675
|
+
pubkey: spotMarketAccount.pubkey,
|
|
1496
1676
|
isSigner: false,
|
|
1497
1677
|
isWritable: false,
|
|
1498
1678
|
});
|
|
1499
1679
|
|
|
1500
|
-
if (!
|
|
1501
|
-
oracleAccountMap.set(
|
|
1502
|
-
pubkey:
|
|
1680
|
+
if (!spotMarketAccount.oracle.equals(PublicKey.default)) {
|
|
1681
|
+
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
1682
|
+
pubkey: spotMarketAccount.oracle,
|
|
1503
1683
|
isSigner: false,
|
|
1504
1684
|
isWritable: false,
|
|
1505
1685
|
});
|
|
@@ -1507,13 +1687,13 @@ export class ClearingHouse {
|
|
|
1507
1687
|
}
|
|
1508
1688
|
}
|
|
1509
1689
|
|
|
1510
|
-
for (const position of userAccount.
|
|
1690
|
+
for (const position of userAccount.perpPositions) {
|
|
1511
1691
|
if (
|
|
1512
1692
|
!positionIsAvailable(position) &&
|
|
1513
1693
|
!position.marketIndex.eq(order.marketIndex)
|
|
1514
1694
|
) {
|
|
1515
|
-
const market = this.
|
|
1516
|
-
|
|
1695
|
+
const market = this.getPerpMarketAccount(position.marketIndex);
|
|
1696
|
+
perpMarketAccountMap.set(position.marketIndex.toNumber(), {
|
|
1517
1697
|
pubkey: market.pubkey,
|
|
1518
1698
|
isWritable: false,
|
|
1519
1699
|
isSigner: false,
|
|
@@ -1526,7 +1706,7 @@ export class ClearingHouse {
|
|
|
1526
1706
|
}
|
|
1527
1707
|
}
|
|
1528
1708
|
|
|
1529
|
-
|
|
1709
|
+
perpMarketAccountMap.set(marketIndex.toNumber(), {
|
|
1530
1710
|
pubkey: marketAccount.pubkey,
|
|
1531
1711
|
isWritable: true,
|
|
1532
1712
|
isSigner: false,
|
|
@@ -1539,8 +1719,8 @@ export class ClearingHouse {
|
|
|
1539
1719
|
|
|
1540
1720
|
const remainingAccounts = [
|
|
1541
1721
|
...oracleAccountMap.values(),
|
|
1542
|
-
...
|
|
1543
|
-
...
|
|
1722
|
+
...spotMarketAccountMap.values(),
|
|
1723
|
+
...perpMarketAccountMap.values(),
|
|
1544
1724
|
];
|
|
1545
1725
|
|
|
1546
1726
|
if (makerInfo) {
|
|
@@ -1585,45 +1765,101 @@ export class ClearingHouse {
|
|
|
1585
1765
|
});
|
|
1586
1766
|
}
|
|
1587
1767
|
|
|
1588
|
-
public async
|
|
1768
|
+
public async placeSpotOrder(
|
|
1769
|
+
orderParams: OptionalOrderParams
|
|
1770
|
+
): Promise<TransactionSignature> {
|
|
1771
|
+
const { txSig } = await this.txSender.send(
|
|
1772
|
+
wrapInTx(await this.getPlaceSpotOrderIx(orderParams)),
|
|
1773
|
+
[],
|
|
1774
|
+
this.opts
|
|
1775
|
+
);
|
|
1776
|
+
return txSig;
|
|
1777
|
+
}
|
|
1778
|
+
|
|
1779
|
+
public async getPlaceSpotOrderIx(
|
|
1780
|
+
orderParams: OptionalOrderParams
|
|
1781
|
+
): Promise<TransactionInstruction> {
|
|
1782
|
+
orderParams = this.getOrderParams(orderParams, MarketType.SPOT);
|
|
1783
|
+
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
1784
|
+
|
|
1785
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
1786
|
+
readableSpotMarketIndex: orderParams.marketIndex,
|
|
1787
|
+
});
|
|
1788
|
+
|
|
1789
|
+
return await this.program.instruction.placeSpotOrder(orderParams, {
|
|
1790
|
+
accounts: {
|
|
1791
|
+
state: await this.getStatePublicKey(),
|
|
1792
|
+
user: userAccountPublicKey,
|
|
1793
|
+
userStats: this.getUserStatsAccountPublicKey(),
|
|
1794
|
+
authority: this.wallet.publicKey,
|
|
1795
|
+
},
|
|
1796
|
+
remainingAccounts,
|
|
1797
|
+
});
|
|
1798
|
+
}
|
|
1799
|
+
|
|
1800
|
+
public async fillSpotOrder(
|
|
1589
1801
|
userAccountPublicKey: PublicKey,
|
|
1590
1802
|
user: UserAccount,
|
|
1591
|
-
order
|
|
1803
|
+
order?: Order,
|
|
1804
|
+
fulfillmentConfig?: SerumV3FulfillmentConfigAccount,
|
|
1805
|
+
makerInfo?: MakerInfo,
|
|
1806
|
+
referrerInfo?: ReferrerInfo
|
|
1592
1807
|
): Promise<TransactionSignature> {
|
|
1593
1808
|
const { txSig } = await this.txSender.send(
|
|
1594
|
-
wrapInTx(
|
|
1809
|
+
wrapInTx(
|
|
1810
|
+
await this.getFillSpotOrderIx(
|
|
1811
|
+
userAccountPublicKey,
|
|
1812
|
+
user,
|
|
1813
|
+
order,
|
|
1814
|
+
fulfillmentConfig,
|
|
1815
|
+
makerInfo,
|
|
1816
|
+
referrerInfo
|
|
1817
|
+
)
|
|
1818
|
+
),
|
|
1595
1819
|
[],
|
|
1596
1820
|
this.opts
|
|
1597
1821
|
);
|
|
1598
1822
|
return txSig;
|
|
1599
1823
|
}
|
|
1600
1824
|
|
|
1601
|
-
public async
|
|
1825
|
+
public async getFillSpotOrderIx(
|
|
1602
1826
|
userAccountPublicKey: PublicKey,
|
|
1603
1827
|
userAccount: UserAccount,
|
|
1604
|
-
order
|
|
1828
|
+
order?: Order,
|
|
1829
|
+
fulfillmentConfig?: SerumV3FulfillmentConfigAccount,
|
|
1830
|
+
makerInfo?: MakerInfo,
|
|
1831
|
+
referrerInfo?: ReferrerInfo
|
|
1605
1832
|
): Promise<TransactionInstruction> {
|
|
1833
|
+
const userStatsPublicKey = getUserStatsAccountPublicKey(
|
|
1834
|
+
this.program.programId,
|
|
1835
|
+
userAccount.authority
|
|
1836
|
+
);
|
|
1837
|
+
|
|
1606
1838
|
const fillerPublicKey = await this.getUserAccountPublicKey();
|
|
1839
|
+
const fillerStatsPublicKey = this.getUserStatsAccountPublicKey();
|
|
1607
1840
|
|
|
1608
|
-
const marketIndex = order
|
|
1609
|
-
|
|
1841
|
+
const marketIndex = order
|
|
1842
|
+
? order.marketIndex
|
|
1843
|
+
: userAccount.orders.find((order) =>
|
|
1844
|
+
order.orderId.eq(userAccount.nextOrderId.sub(ONE))
|
|
1845
|
+
).marketIndex;
|
|
1610
1846
|
|
|
1611
1847
|
const oracleAccountMap = new Map<string, AccountMeta>();
|
|
1612
|
-
const
|
|
1613
|
-
const
|
|
1614
|
-
|
|
1615
|
-
for (const
|
|
1616
|
-
if (!
|
|
1617
|
-
const
|
|
1618
|
-
|
|
1619
|
-
pubkey:
|
|
1848
|
+
const spotMarketAccountMap = new Map<number, AccountMeta>();
|
|
1849
|
+
const perpMarketAccountMap = new Map<number, AccountMeta>();
|
|
1850
|
+
|
|
1851
|
+
for (const spotPosition of userAccount.spotPositions) {
|
|
1852
|
+
if (!isSpotPositionAvailable(spotPosition)) {
|
|
1853
|
+
const spotMarket = this.getSpotMarketAccount(spotPosition.marketIndex);
|
|
1854
|
+
spotMarketAccountMap.set(spotPosition.marketIndex.toNumber(), {
|
|
1855
|
+
pubkey: spotMarket.pubkey,
|
|
1620
1856
|
isSigner: false,
|
|
1621
1857
|
isWritable: false,
|
|
1622
1858
|
});
|
|
1623
1859
|
|
|
1624
|
-
if (!
|
|
1625
|
-
oracleAccountMap.set(
|
|
1626
|
-
pubkey:
|
|
1860
|
+
if (!spotMarket.oracle.equals(PublicKey.default)) {
|
|
1861
|
+
oracleAccountMap.set(spotMarket.oracle.toString(), {
|
|
1862
|
+
pubkey: spotMarket.oracle,
|
|
1627
1863
|
isSigner: false,
|
|
1628
1864
|
isWritable: false,
|
|
1629
1865
|
});
|
|
@@ -1631,13 +1867,13 @@ export class ClearingHouse {
|
|
|
1631
1867
|
}
|
|
1632
1868
|
}
|
|
1633
1869
|
|
|
1634
|
-
for (const position of userAccount.
|
|
1870
|
+
for (const position of userAccount.perpPositions) {
|
|
1635
1871
|
if (
|
|
1636
1872
|
!positionIsAvailable(position) &&
|
|
1637
1873
|
!position.marketIndex.eq(order.marketIndex)
|
|
1638
1874
|
) {
|
|
1639
|
-
const market = this.
|
|
1640
|
-
|
|
1875
|
+
const market = this.getPerpMarketAccount(position.marketIndex);
|
|
1876
|
+
perpMarketAccountMap.set(position.marketIndex.toNumber(), {
|
|
1641
1877
|
pubkey: market.pubkey,
|
|
1642
1878
|
isWritable: false,
|
|
1643
1879
|
isSigner: false,
|
|
@@ -1650,77 +1886,42 @@ export class ClearingHouse {
|
|
|
1650
1886
|
}
|
|
1651
1887
|
}
|
|
1652
1888
|
|
|
1653
|
-
|
|
1654
|
-
|
|
1889
|
+
const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
|
|
1890
|
+
spotMarketAccountMap.set(marketIndex.toNumber(), {
|
|
1891
|
+
pubkey: spotMarketAccount.pubkey,
|
|
1655
1892
|
isWritable: true,
|
|
1656
1893
|
isSigner: false,
|
|
1657
1894
|
});
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1895
|
+
if (!spotMarketAccount.oracle.equals(PublicKey.default)) {
|
|
1896
|
+
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
1897
|
+
pubkey: spotMarketAccount.oracle,
|
|
1898
|
+
isWritable: false,
|
|
1899
|
+
isSigner: false,
|
|
1900
|
+
});
|
|
1901
|
+
}
|
|
1902
|
+
const quoteMarketAccount = this.getQuoteSpotMarketAccount();
|
|
1903
|
+
spotMarketAccountMap.set(quoteMarketAccount.marketIndex.toNumber(), {
|
|
1904
|
+
pubkey: quoteMarketAccount.pubkey,
|
|
1905
|
+
isWritable: true,
|
|
1661
1906
|
isSigner: false,
|
|
1662
1907
|
});
|
|
1663
1908
|
|
|
1664
1909
|
const remainingAccounts = [
|
|
1665
1910
|
...oracleAccountMap.values(),
|
|
1666
|
-
...
|
|
1667
|
-
...
|
|
1911
|
+
...spotMarketAccountMap.values(),
|
|
1912
|
+
...perpMarketAccountMap.values(),
|
|
1668
1913
|
];
|
|
1669
1914
|
|
|
1670
|
-
const orderId = order.orderId;
|
|
1671
|
-
return await this.program.instruction.triggerOrder(orderId, {
|
|
1672
|
-
accounts: {
|
|
1673
|
-
state: await this.getStatePublicKey(),
|
|
1674
|
-
filler: fillerPublicKey,
|
|
1675
|
-
user: userAccountPublicKey,
|
|
1676
|
-
authority: this.wallet.publicKey,
|
|
1677
|
-
},
|
|
1678
|
-
remainingAccounts,
|
|
1679
|
-
});
|
|
1680
|
-
}
|
|
1681
|
-
|
|
1682
|
-
public async placeAndTake(
|
|
1683
|
-
orderParams: OptionalOrderParams,
|
|
1684
|
-
makerInfo?: MakerInfo,
|
|
1685
|
-
referrerInfo?: ReferrerInfo
|
|
1686
|
-
): Promise<TransactionSignature> {
|
|
1687
|
-
const { txSig, slot } = await this.txSender.send(
|
|
1688
|
-
wrapInTx(
|
|
1689
|
-
await this.getPlaceAndTakeIx(orderParams, makerInfo, referrerInfo)
|
|
1690
|
-
),
|
|
1691
|
-
[],
|
|
1692
|
-
this.opts
|
|
1693
|
-
);
|
|
1694
|
-
this.marketLastSlotCache.set(orderParams.marketIndex.toNumber(), slot);
|
|
1695
|
-
return txSig;
|
|
1696
|
-
}
|
|
1697
|
-
|
|
1698
|
-
public async getPlaceAndTakeIx(
|
|
1699
|
-
orderParams: OptionalOrderParams,
|
|
1700
|
-
makerInfo?: MakerInfo,
|
|
1701
|
-
referrerInfo?: ReferrerInfo
|
|
1702
|
-
): Promise<TransactionInstruction> {
|
|
1703
|
-
orderParams = this.getOrderParams(orderParams);
|
|
1704
|
-
const userStatsPublicKey = await this.getUserStatsAccountPublicKey();
|
|
1705
|
-
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
1706
|
-
|
|
1707
|
-
const remainingAccounts = this.getRemainingAccounts({
|
|
1708
|
-
writableMarketIndex: orderParams.marketIndex,
|
|
1709
|
-
writableBankIndex: QUOTE_ASSET_BANK_INDEX,
|
|
1710
|
-
});
|
|
1711
|
-
|
|
1712
|
-
let makerOrderId = null;
|
|
1713
1915
|
if (makerInfo) {
|
|
1714
|
-
makerOrderId = makerInfo.order.orderId;
|
|
1715
1916
|
remainingAccounts.push({
|
|
1716
1917
|
pubkey: makerInfo.maker,
|
|
1717
|
-
isSigner: false,
|
|
1718
1918
|
isWritable: true,
|
|
1919
|
+
isSigner: false,
|
|
1719
1920
|
});
|
|
1720
1921
|
remainingAccounts.push({
|
|
1721
1922
|
pubkey: makerInfo.makerStats,
|
|
1722
|
-
isSigner: false,
|
|
1723
1923
|
isWritable: true,
|
|
1924
|
+
isSigner: false,
|
|
1724
1925
|
});
|
|
1725
1926
|
}
|
|
1726
1927
|
|
|
@@ -1737,24 +1938,385 @@ export class ClearingHouse {
|
|
|
1737
1938
|
});
|
|
1738
1939
|
}
|
|
1739
1940
|
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
makerOrderId,
|
|
1743
|
-
{
|
|
1744
|
-
accounts: {
|
|
1745
|
-
state: await this.getStatePublicKey(),
|
|
1746
|
-
user: userAccountPublicKey,
|
|
1747
|
-
userStats: userStatsPublicKey,
|
|
1748
|
-
authority: this.wallet.publicKey,
|
|
1749
|
-
},
|
|
1750
|
-
remainingAccounts,
|
|
1751
|
-
}
|
|
1752
|
-
);
|
|
1753
|
-
}
|
|
1941
|
+
const orderId = order.orderId;
|
|
1942
|
+
const makerOrderId = makerInfo ? makerInfo.order.orderId : null;
|
|
1754
1943
|
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1944
|
+
if (fulfillmentConfig) {
|
|
1945
|
+
remainingAccounts.push({
|
|
1946
|
+
pubkey: fulfillmentConfig.pubkey,
|
|
1947
|
+
isWritable: false,
|
|
1948
|
+
isSigner: false,
|
|
1949
|
+
});
|
|
1950
|
+
remainingAccounts.push({
|
|
1951
|
+
pubkey: fulfillmentConfig.serumProgramId,
|
|
1952
|
+
isWritable: false,
|
|
1953
|
+
isSigner: false,
|
|
1954
|
+
});
|
|
1955
|
+
remainingAccounts.push({
|
|
1956
|
+
pubkey: fulfillmentConfig.serumMarket,
|
|
1957
|
+
isWritable: true,
|
|
1958
|
+
isSigner: false,
|
|
1959
|
+
});
|
|
1960
|
+
remainingAccounts.push({
|
|
1961
|
+
pubkey: fulfillmentConfig.serumRequestQueue,
|
|
1962
|
+
isWritable: true,
|
|
1963
|
+
isSigner: false,
|
|
1964
|
+
});
|
|
1965
|
+
remainingAccounts.push({
|
|
1966
|
+
pubkey: fulfillmentConfig.serumEventQueue,
|
|
1967
|
+
isWritable: true,
|
|
1968
|
+
isSigner: false,
|
|
1969
|
+
});
|
|
1970
|
+
remainingAccounts.push({
|
|
1971
|
+
pubkey: fulfillmentConfig.serumBids,
|
|
1972
|
+
isWritable: true,
|
|
1973
|
+
isSigner: false,
|
|
1974
|
+
});
|
|
1975
|
+
remainingAccounts.push({
|
|
1976
|
+
pubkey: fulfillmentConfig.serumAsks,
|
|
1977
|
+
isWritable: true,
|
|
1978
|
+
isSigner: false,
|
|
1979
|
+
});
|
|
1980
|
+
remainingAccounts.push({
|
|
1981
|
+
pubkey: fulfillmentConfig.serumBaseVault,
|
|
1982
|
+
isWritable: true,
|
|
1983
|
+
isSigner: false,
|
|
1984
|
+
});
|
|
1985
|
+
remainingAccounts.push({
|
|
1986
|
+
pubkey: fulfillmentConfig.serumQuoteVault,
|
|
1987
|
+
isWritable: true,
|
|
1988
|
+
isSigner: false,
|
|
1989
|
+
});
|
|
1990
|
+
remainingAccounts.push({
|
|
1991
|
+
pubkey: fulfillmentConfig.serumOpenOrders,
|
|
1992
|
+
isWritable: true,
|
|
1993
|
+
isSigner: false,
|
|
1994
|
+
});
|
|
1995
|
+
remainingAccounts.push({
|
|
1996
|
+
pubkey: getSerumSignerPublicKey(
|
|
1997
|
+
fulfillmentConfig.serumProgramId,
|
|
1998
|
+
fulfillmentConfig.serumMarket,
|
|
1999
|
+
fulfillmentConfig.serumSignerNonce
|
|
2000
|
+
),
|
|
2001
|
+
isWritable: false,
|
|
2002
|
+
isSigner: false,
|
|
2003
|
+
});
|
|
2004
|
+
remainingAccounts.push({
|
|
2005
|
+
pubkey: this.getSignerPublicKey(),
|
|
2006
|
+
isWritable: false,
|
|
2007
|
+
isSigner: false,
|
|
2008
|
+
});
|
|
2009
|
+
remainingAccounts.push({
|
|
2010
|
+
pubkey: TOKEN_PROGRAM_ID,
|
|
2011
|
+
isWritable: false,
|
|
2012
|
+
isSigner: false,
|
|
2013
|
+
});
|
|
2014
|
+
remainingAccounts.push({
|
|
2015
|
+
pubkey: spotMarketAccount.vault,
|
|
2016
|
+
isWritable: true,
|
|
2017
|
+
isSigner: false,
|
|
2018
|
+
});
|
|
2019
|
+
remainingAccounts.push({
|
|
2020
|
+
pubkey: quoteMarketAccount.vault,
|
|
2021
|
+
isWritable: true,
|
|
2022
|
+
isSigner: false,
|
|
2023
|
+
});
|
|
2024
|
+
}
|
|
2025
|
+
|
|
2026
|
+
return await this.program.instruction.fillSpotOrder(
|
|
2027
|
+
orderId,
|
|
2028
|
+
fulfillmentConfig ? fulfillmentConfig.fulfillmentType : null,
|
|
2029
|
+
makerOrderId,
|
|
2030
|
+
{
|
|
2031
|
+
accounts: {
|
|
2032
|
+
state: await this.getStatePublicKey(),
|
|
2033
|
+
filler: fillerPublicKey,
|
|
2034
|
+
fillerStats: fillerStatsPublicKey,
|
|
2035
|
+
user: userAccountPublicKey,
|
|
2036
|
+
userStats: userStatsPublicKey,
|
|
2037
|
+
authority: this.wallet.publicKey,
|
|
2038
|
+
},
|
|
2039
|
+
remainingAccounts,
|
|
2040
|
+
}
|
|
2041
|
+
);
|
|
2042
|
+
}
|
|
2043
|
+
|
|
2044
|
+
public async triggerOrder(
|
|
2045
|
+
userAccountPublicKey: PublicKey,
|
|
2046
|
+
user: UserAccount,
|
|
2047
|
+
order: Order
|
|
2048
|
+
): Promise<TransactionSignature> {
|
|
2049
|
+
const { txSig } = await this.txSender.send(
|
|
2050
|
+
wrapInTx(await this.getTriggerOrderIx(userAccountPublicKey, user, order)),
|
|
2051
|
+
[],
|
|
2052
|
+
this.opts
|
|
2053
|
+
);
|
|
2054
|
+
return txSig;
|
|
2055
|
+
}
|
|
2056
|
+
|
|
2057
|
+
public async getTriggerOrderIx(
|
|
2058
|
+
userAccountPublicKey: PublicKey,
|
|
2059
|
+
userAccount: UserAccount,
|
|
2060
|
+
order: Order
|
|
2061
|
+
): Promise<TransactionInstruction> {
|
|
2062
|
+
const fillerPublicKey = await this.getUserAccountPublicKey();
|
|
2063
|
+
|
|
2064
|
+
const marketIndex = order.marketIndex;
|
|
2065
|
+
const marketAccount = this.getPerpMarketAccount(marketIndex);
|
|
2066
|
+
|
|
2067
|
+
const oracleAccountMap = new Map<string, AccountMeta>();
|
|
2068
|
+
const spotMarketAccountMap = new Map<number, AccountMeta>();
|
|
2069
|
+
const perpMarketAccountMap = new Map<number, AccountMeta>();
|
|
2070
|
+
|
|
2071
|
+
for (const spotPosition of userAccount.spotPositions) {
|
|
2072
|
+
if (!isSpotPositionAvailable(spotPosition)) {
|
|
2073
|
+
const spotMarketAccount = this.getSpotMarketAccount(
|
|
2074
|
+
spotPosition.marketIndex
|
|
2075
|
+
);
|
|
2076
|
+
spotMarketAccountMap.set(spotPosition.marketIndex.toNumber(), {
|
|
2077
|
+
pubkey: spotMarketAccount.pubkey,
|
|
2078
|
+
isSigner: false,
|
|
2079
|
+
isWritable: false,
|
|
2080
|
+
});
|
|
2081
|
+
|
|
2082
|
+
if (!spotMarketAccount.oracle.equals(PublicKey.default)) {
|
|
2083
|
+
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
2084
|
+
pubkey: spotMarketAccount.oracle,
|
|
2085
|
+
isSigner: false,
|
|
2086
|
+
isWritable: false,
|
|
2087
|
+
});
|
|
2088
|
+
}
|
|
2089
|
+
}
|
|
2090
|
+
}
|
|
2091
|
+
|
|
2092
|
+
for (const position of userAccount.perpPositions) {
|
|
2093
|
+
if (
|
|
2094
|
+
!positionIsAvailable(position) &&
|
|
2095
|
+
!position.marketIndex.eq(order.marketIndex)
|
|
2096
|
+
) {
|
|
2097
|
+
const market = this.getPerpMarketAccount(position.marketIndex);
|
|
2098
|
+
perpMarketAccountMap.set(position.marketIndex.toNumber(), {
|
|
2099
|
+
pubkey: market.pubkey,
|
|
2100
|
+
isWritable: false,
|
|
2101
|
+
isSigner: false,
|
|
2102
|
+
});
|
|
2103
|
+
oracleAccountMap.set(market.amm.oracle.toString(), {
|
|
2104
|
+
pubkey: market.amm.oracle,
|
|
2105
|
+
isWritable: false,
|
|
2106
|
+
isSigner: false,
|
|
2107
|
+
});
|
|
2108
|
+
}
|
|
2109
|
+
}
|
|
2110
|
+
|
|
2111
|
+
perpMarketAccountMap.set(marketIndex.toNumber(), {
|
|
2112
|
+
pubkey: marketAccount.pubkey,
|
|
2113
|
+
isWritable: true,
|
|
2114
|
+
isSigner: false,
|
|
2115
|
+
});
|
|
2116
|
+
oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
|
|
2117
|
+
pubkey: marketAccount.amm.oracle,
|
|
2118
|
+
isWritable: false,
|
|
2119
|
+
isSigner: false,
|
|
2120
|
+
});
|
|
2121
|
+
|
|
2122
|
+
const remainingAccounts = [
|
|
2123
|
+
...oracleAccountMap.values(),
|
|
2124
|
+
...spotMarketAccountMap.values(),
|
|
2125
|
+
...perpMarketAccountMap.values(),
|
|
2126
|
+
];
|
|
2127
|
+
|
|
2128
|
+
const orderId = order.orderId;
|
|
2129
|
+
return await this.program.instruction.triggerOrder(orderId, {
|
|
2130
|
+
accounts: {
|
|
2131
|
+
state: await this.getStatePublicKey(),
|
|
2132
|
+
filler: fillerPublicKey,
|
|
2133
|
+
user: userAccountPublicKey,
|
|
2134
|
+
authority: this.wallet.publicKey,
|
|
2135
|
+
},
|
|
2136
|
+
remainingAccounts,
|
|
2137
|
+
});
|
|
2138
|
+
}
|
|
2139
|
+
|
|
2140
|
+
public async triggerSpotOrder(
|
|
2141
|
+
userAccountPublicKey: PublicKey,
|
|
2142
|
+
user: UserAccount,
|
|
2143
|
+
order: Order
|
|
2144
|
+
): Promise<TransactionSignature> {
|
|
2145
|
+
const { txSig } = await this.txSender.send(
|
|
2146
|
+
wrapInTx(
|
|
2147
|
+
await this.getTriggerSpotOrderIx(userAccountPublicKey, user, order)
|
|
2148
|
+
),
|
|
2149
|
+
[],
|
|
2150
|
+
this.opts
|
|
2151
|
+
);
|
|
2152
|
+
return txSig;
|
|
2153
|
+
}
|
|
2154
|
+
|
|
2155
|
+
public async getTriggerSpotOrderIx(
|
|
2156
|
+
userAccountPublicKey: PublicKey,
|
|
2157
|
+
userAccount: UserAccount,
|
|
2158
|
+
order: Order
|
|
2159
|
+
): Promise<TransactionInstruction> {
|
|
2160
|
+
const fillerPublicKey = await this.getUserAccountPublicKey();
|
|
2161
|
+
|
|
2162
|
+
const marketIndex = order.marketIndex;
|
|
2163
|
+
const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
|
|
2164
|
+
|
|
2165
|
+
const oracleAccountMap = new Map<string, AccountMeta>();
|
|
2166
|
+
const spotMarketAccountMap = new Map<number, AccountMeta>();
|
|
2167
|
+
const perpMarketAccountMap = new Map<number, AccountMeta>();
|
|
2168
|
+
|
|
2169
|
+
for (const spotPosition of userAccount.spotPositions) {
|
|
2170
|
+
if (!isSpotPositionAvailable(spotPosition)) {
|
|
2171
|
+
const spotMarketAccount = this.getSpotMarketAccount(
|
|
2172
|
+
spotPosition.marketIndex
|
|
2173
|
+
);
|
|
2174
|
+
spotMarketAccountMap.set(spotPosition.marketIndex.toNumber(), {
|
|
2175
|
+
pubkey: spotMarketAccount.pubkey,
|
|
2176
|
+
isSigner: false,
|
|
2177
|
+
isWritable: false,
|
|
2178
|
+
});
|
|
2179
|
+
|
|
2180
|
+
if (!spotMarketAccount.oracle.equals(PublicKey.default)) {
|
|
2181
|
+
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
2182
|
+
pubkey: spotMarketAccount.oracle,
|
|
2183
|
+
isSigner: false,
|
|
2184
|
+
isWritable: false,
|
|
2185
|
+
});
|
|
2186
|
+
}
|
|
2187
|
+
}
|
|
2188
|
+
}
|
|
2189
|
+
|
|
2190
|
+
for (const position of userAccount.perpPositions) {
|
|
2191
|
+
if (
|
|
2192
|
+
!positionIsAvailable(position) &&
|
|
2193
|
+
!position.marketIndex.eq(order.marketIndex)
|
|
2194
|
+
) {
|
|
2195
|
+
const market = this.getPerpMarketAccount(position.marketIndex);
|
|
2196
|
+
perpMarketAccountMap.set(position.marketIndex.toNumber(), {
|
|
2197
|
+
pubkey: market.pubkey,
|
|
2198
|
+
isWritable: false,
|
|
2199
|
+
isSigner: false,
|
|
2200
|
+
});
|
|
2201
|
+
oracleAccountMap.set(market.amm.oracle.toString(), {
|
|
2202
|
+
pubkey: market.amm.oracle,
|
|
2203
|
+
isWritable: false,
|
|
2204
|
+
isSigner: false,
|
|
2205
|
+
});
|
|
2206
|
+
}
|
|
2207
|
+
}
|
|
2208
|
+
|
|
2209
|
+
const quoteSpotMarket = this.getQuoteSpotMarketAccount();
|
|
2210
|
+
spotMarketAccountMap.set(quoteSpotMarket.marketIndex.toNumber(), {
|
|
2211
|
+
pubkey: quoteSpotMarket.pubkey,
|
|
2212
|
+
isWritable: true,
|
|
2213
|
+
isSigner: false,
|
|
2214
|
+
});
|
|
2215
|
+
spotMarketAccountMap.set(marketIndex.toNumber(), {
|
|
2216
|
+
pubkey: spotMarketAccount.pubkey,
|
|
2217
|
+
isWritable: false,
|
|
2218
|
+
isSigner: false,
|
|
2219
|
+
});
|
|
2220
|
+
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
2221
|
+
pubkey: spotMarketAccount.oracle,
|
|
2222
|
+
isWritable: false,
|
|
2223
|
+
isSigner: false,
|
|
2224
|
+
});
|
|
2225
|
+
|
|
2226
|
+
const remainingAccounts = [
|
|
2227
|
+
...oracleAccountMap.values(),
|
|
2228
|
+
...spotMarketAccountMap.values(),
|
|
2229
|
+
...perpMarketAccountMap.values(),
|
|
2230
|
+
];
|
|
2231
|
+
|
|
2232
|
+
const orderId = order.orderId;
|
|
2233
|
+
return await this.program.instruction.triggerSpotOrder(orderId, {
|
|
2234
|
+
accounts: {
|
|
2235
|
+
state: await this.getStatePublicKey(),
|
|
2236
|
+
filler: fillerPublicKey,
|
|
2237
|
+
user: userAccountPublicKey,
|
|
2238
|
+
authority: this.wallet.publicKey,
|
|
2239
|
+
},
|
|
2240
|
+
remainingAccounts,
|
|
2241
|
+
});
|
|
2242
|
+
}
|
|
2243
|
+
|
|
2244
|
+
public async placeAndTake(
|
|
2245
|
+
orderParams: OptionalOrderParams,
|
|
2246
|
+
makerInfo?: MakerInfo,
|
|
2247
|
+
referrerInfo?: ReferrerInfo
|
|
2248
|
+
): Promise<TransactionSignature> {
|
|
2249
|
+
const { txSig, slot } = await this.txSender.send(
|
|
2250
|
+
wrapInTx(
|
|
2251
|
+
await this.getPlaceAndTakeIx(orderParams, makerInfo, referrerInfo)
|
|
2252
|
+
),
|
|
2253
|
+
[],
|
|
2254
|
+
this.opts
|
|
2255
|
+
);
|
|
2256
|
+
this.marketLastSlotCache.set(orderParams.marketIndex.toNumber(), slot);
|
|
2257
|
+
return txSig;
|
|
2258
|
+
}
|
|
2259
|
+
|
|
2260
|
+
public async getPlaceAndTakeIx(
|
|
2261
|
+
orderParams: OptionalOrderParams,
|
|
2262
|
+
makerInfo?: MakerInfo,
|
|
2263
|
+
referrerInfo?: ReferrerInfo
|
|
2264
|
+
): Promise<TransactionInstruction> {
|
|
2265
|
+
orderParams = this.getOrderParams(orderParams, MarketType.PERP);
|
|
2266
|
+
const userStatsPublicKey = await this.getUserStatsAccountPublicKey();
|
|
2267
|
+
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
2268
|
+
|
|
2269
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
2270
|
+
writablePerpMarketIndex: orderParams.marketIndex,
|
|
2271
|
+
writableSpotMarketIndex: QUOTE_SPOT_MARKET_INDEX,
|
|
2272
|
+
});
|
|
2273
|
+
|
|
2274
|
+
let makerOrderId = null;
|
|
2275
|
+
if (makerInfo) {
|
|
2276
|
+
makerOrderId = makerInfo.order.orderId;
|
|
2277
|
+
remainingAccounts.push({
|
|
2278
|
+
pubkey: makerInfo.maker,
|
|
2279
|
+
isSigner: false,
|
|
2280
|
+
isWritable: true,
|
|
2281
|
+
});
|
|
2282
|
+
remainingAccounts.push({
|
|
2283
|
+
pubkey: makerInfo.makerStats,
|
|
2284
|
+
isSigner: false,
|
|
2285
|
+
isWritable: true,
|
|
2286
|
+
});
|
|
2287
|
+
}
|
|
2288
|
+
|
|
2289
|
+
if (referrerInfo) {
|
|
2290
|
+
remainingAccounts.push({
|
|
2291
|
+
pubkey: referrerInfo.referrer,
|
|
2292
|
+
isWritable: true,
|
|
2293
|
+
isSigner: false,
|
|
2294
|
+
});
|
|
2295
|
+
remainingAccounts.push({
|
|
2296
|
+
pubkey: referrerInfo.referrerStats,
|
|
2297
|
+
isWritable: true,
|
|
2298
|
+
isSigner: false,
|
|
2299
|
+
});
|
|
2300
|
+
}
|
|
2301
|
+
|
|
2302
|
+
return await this.program.instruction.placeAndTake(
|
|
2303
|
+
orderParams,
|
|
2304
|
+
makerOrderId,
|
|
2305
|
+
{
|
|
2306
|
+
accounts: {
|
|
2307
|
+
state: await this.getStatePublicKey(),
|
|
2308
|
+
user: userAccountPublicKey,
|
|
2309
|
+
userStats: userStatsPublicKey,
|
|
2310
|
+
authority: this.wallet.publicKey,
|
|
2311
|
+
},
|
|
2312
|
+
remainingAccounts,
|
|
2313
|
+
}
|
|
2314
|
+
);
|
|
2315
|
+
}
|
|
2316
|
+
|
|
2317
|
+
public async placeAndMake(
|
|
2318
|
+
orderParams: OptionalOrderParams,
|
|
2319
|
+
takerInfo: TakerInfo,
|
|
1758
2320
|
referrerInfo?: ReferrerInfo
|
|
1759
2321
|
): Promise<TransactionSignature> {
|
|
1760
2322
|
const { txSig, slot } = await this.txSender.send(
|
|
@@ -1775,14 +2337,14 @@ export class ClearingHouse {
|
|
|
1775
2337
|
takerInfo: TakerInfo,
|
|
1776
2338
|
referrerInfo?: ReferrerInfo
|
|
1777
2339
|
): Promise<TransactionInstruction> {
|
|
1778
|
-
orderParams = this.getOrderParams(orderParams);
|
|
2340
|
+
orderParams = this.getOrderParams(orderParams, MarketType.PERP);
|
|
1779
2341
|
const userStatsPublicKey = this.getUserStatsAccountPublicKey();
|
|
1780
2342
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
1781
2343
|
|
|
1782
2344
|
// todo merge this with getRemainingAccounts
|
|
1783
2345
|
const remainingAccounts = this.getRemainingAccountsWithCounterparty({
|
|
1784
2346
|
counterPartyUserAccount: takerInfo.takerUserAccount,
|
|
1785
|
-
|
|
2347
|
+
writablePerpMarketIndex: orderParams.marketIndex,
|
|
1786
2348
|
});
|
|
1787
2349
|
|
|
1788
2350
|
if (referrerInfo) {
|
|
@@ -1895,13 +2457,110 @@ export class ClearingHouse {
|
|
|
1895
2457
|
settleeUserAccount: UserAccount,
|
|
1896
2458
|
marketIndex: BN
|
|
1897
2459
|
): Promise<TransactionInstruction> {
|
|
1898
|
-
const
|
|
2460
|
+
const perpMarketAccountMap = new Map<number, AccountMeta>();
|
|
1899
2461
|
const oracleAccountMap = new Map<string, AccountMeta>();
|
|
1900
|
-
const
|
|
2462
|
+
const spotMarketAccountMap = new Map<number, AccountMeta>();
|
|
2463
|
+
|
|
2464
|
+
for (const position of settleeUserAccount.perpPositions) {
|
|
2465
|
+
if (!positionIsAvailable(position)) {
|
|
2466
|
+
const market = this.getPerpMarketAccount(position.marketIndex);
|
|
2467
|
+
perpMarketAccountMap.set(position.marketIndex.toNumber(), {
|
|
2468
|
+
pubkey: market.pubkey,
|
|
2469
|
+
isWritable: false,
|
|
2470
|
+
isSigner: false,
|
|
2471
|
+
});
|
|
2472
|
+
oracleAccountMap.set(market.amm.oracle.toString(), {
|
|
2473
|
+
pubkey: market.amm.oracle,
|
|
2474
|
+
isWritable: false,
|
|
2475
|
+
isSigner: false,
|
|
2476
|
+
});
|
|
2477
|
+
}
|
|
2478
|
+
}
|
|
2479
|
+
|
|
2480
|
+
for (const spotPosition of settleeUserAccount.spotPositions) {
|
|
2481
|
+
if (!isSpotPositionAvailable(spotPosition)) {
|
|
2482
|
+
const spotMarketAccount = this.getSpotMarketAccount(
|
|
2483
|
+
spotPosition.marketIndex
|
|
2484
|
+
);
|
|
2485
|
+
spotMarketAccountMap.set(spotPosition.marketIndex.toNumber(), {
|
|
2486
|
+
pubkey: spotMarketAccount.pubkey,
|
|
2487
|
+
isSigner: false,
|
|
2488
|
+
isWritable: false,
|
|
2489
|
+
});
|
|
2490
|
+
if (!spotMarketAccount.marketIndex.eq(ZERO)) {
|
|
2491
|
+
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
2492
|
+
pubkey: spotMarketAccount.oracle,
|
|
2493
|
+
isSigner: false,
|
|
2494
|
+
isWritable: false,
|
|
2495
|
+
});
|
|
2496
|
+
}
|
|
2497
|
+
}
|
|
2498
|
+
}
|
|
1901
2499
|
|
|
1902
|
-
|
|
2500
|
+
const marketAccount = this.getPerpMarketAccount(marketIndex.toNumber());
|
|
2501
|
+
perpMarketAccountMap.set(marketIndex.toNumber(), {
|
|
2502
|
+
pubkey: marketAccount.pubkey,
|
|
2503
|
+
isSigner: false,
|
|
2504
|
+
isWritable: true,
|
|
2505
|
+
});
|
|
2506
|
+
oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
|
|
2507
|
+
pubkey: marketAccount.amm.oracle,
|
|
2508
|
+
isSigner: false,
|
|
2509
|
+
isWritable: false,
|
|
2510
|
+
});
|
|
2511
|
+
|
|
2512
|
+
spotMarketAccountMap.set(QUOTE_SPOT_MARKET_INDEX.toNumber(), {
|
|
2513
|
+
pubkey: this.getSpotMarketAccount(QUOTE_SPOT_MARKET_INDEX).pubkey,
|
|
2514
|
+
isSigner: false,
|
|
2515
|
+
isWritable: true,
|
|
2516
|
+
});
|
|
2517
|
+
|
|
2518
|
+
const remainingAccounts = [
|
|
2519
|
+
...oracleAccountMap.values(),
|
|
2520
|
+
...spotMarketAccountMap.values(),
|
|
2521
|
+
...perpMarketAccountMap.values(),
|
|
2522
|
+
];
|
|
2523
|
+
|
|
2524
|
+
return await this.program.instruction.settlePnl(marketIndex, {
|
|
2525
|
+
accounts: {
|
|
2526
|
+
state: await this.getStatePublicKey(),
|
|
2527
|
+
authority: this.wallet.publicKey,
|
|
2528
|
+
user: settleeUserAccountPublicKey,
|
|
2529
|
+
},
|
|
2530
|
+
remainingAccounts: remainingAccounts,
|
|
2531
|
+
});
|
|
2532
|
+
}
|
|
2533
|
+
|
|
2534
|
+
public async settleExpiredPosition(
|
|
2535
|
+
settleeUserAccountPublicKey: PublicKey,
|
|
2536
|
+
settleeUserAccount: UserAccount,
|
|
2537
|
+
marketIndex: BN
|
|
2538
|
+
): Promise<TransactionSignature> {
|
|
2539
|
+
const { txSig } = await this.txSender.send(
|
|
2540
|
+
wrapInTx(
|
|
2541
|
+
await this.getSettleExpiredPositionIx(
|
|
2542
|
+
settleeUserAccountPublicKey,
|
|
2543
|
+
settleeUserAccount,
|
|
2544
|
+
marketIndex
|
|
2545
|
+
)
|
|
2546
|
+
),
|
|
2547
|
+
[],
|
|
2548
|
+
this.opts
|
|
2549
|
+
);
|
|
2550
|
+
return txSig;
|
|
2551
|
+
}
|
|
2552
|
+
|
|
2553
|
+
public async getSettleExpiredPositionIx(
|
|
2554
|
+
settleeUserAccountPublicKey: PublicKey,
|
|
2555
|
+
settleeUserAccount: UserAccount,
|
|
2556
|
+
marketIndex: BN
|
|
2557
|
+
): Promise<TransactionInstruction> {
|
|
2558
|
+
const marketAccountMap = new Map<number, AccountMeta>();
|
|
2559
|
+
const oracleAccountMap = new Map<string, AccountMeta>();
|
|
2560
|
+
const spotMarketAccountMap = new Map<number, AccountMeta>();
|
|
2561
|
+
for (const position of settleeUserAccount.perpPositions) {
|
|
1903
2562
|
if (!positionIsAvailable(position)) {
|
|
1904
|
-
const market = this.
|
|
2563
|
+
const market = this.getPerpMarketAccount(position.marketIndex);
|
|
1905
2564
|
marketAccountMap.set(position.marketIndex.toNumber(), {
|
|
1906
2565
|
pubkey: market.pubkey,
|
|
1907
2566
|
isWritable: false,
|
|
@@ -1915,15 +2574,17 @@ export class ClearingHouse {
|
|
|
1915
2574
|
}
|
|
1916
2575
|
}
|
|
1917
2576
|
|
|
1918
|
-
for (const userBankBalance of settleeUserAccount.
|
|
1919
|
-
if (!userBankBalance.balance.eq(
|
|
1920
|
-
const bankAccount = this.
|
|
1921
|
-
|
|
2577
|
+
for (const userBankBalance of settleeUserAccount.spotPositions) {
|
|
2578
|
+
if (!userBankBalance.balance.eq(ZERO)) {
|
|
2579
|
+
const bankAccount = this.getSpotMarketAccount(
|
|
2580
|
+
userBankBalance.marketIndex
|
|
2581
|
+
);
|
|
2582
|
+
spotMarketAccountMap.set(userBankBalance.marketIndex.toNumber(), {
|
|
1922
2583
|
pubkey: bankAccount.pubkey,
|
|
1923
2584
|
isSigner: false,
|
|
1924
2585
|
isWritable: false,
|
|
1925
2586
|
});
|
|
1926
|
-
if (!bankAccount.
|
|
2587
|
+
if (!bankAccount.marketIndex.eq(ZERO)) {
|
|
1927
2588
|
oracleAccountMap.set(bankAccount.oracle.toString(), {
|
|
1928
2589
|
pubkey: bankAccount.oracle,
|
|
1929
2590
|
isSigner: false,
|
|
@@ -1933,7 +2594,7 @@ export class ClearingHouse {
|
|
|
1933
2594
|
}
|
|
1934
2595
|
}
|
|
1935
2596
|
|
|
1936
|
-
const marketAccount = this.
|
|
2597
|
+
const marketAccount = this.getPerpMarketAccount(marketIndex.toNumber());
|
|
1937
2598
|
marketAccountMap.set(marketIndex.toNumber(), {
|
|
1938
2599
|
pubkey: marketAccount.pubkey,
|
|
1939
2600
|
isSigner: false,
|
|
@@ -1945,19 +2606,19 @@ export class ClearingHouse {
|
|
|
1945
2606
|
isWritable: false,
|
|
1946
2607
|
});
|
|
1947
2608
|
|
|
1948
|
-
|
|
1949
|
-
pubkey: this.
|
|
2609
|
+
spotMarketAccountMap.set(QUOTE_SPOT_MARKET_INDEX.toNumber(), {
|
|
2610
|
+
pubkey: this.getSpotMarketAccount(QUOTE_SPOT_MARKET_INDEX).pubkey,
|
|
1950
2611
|
isSigner: false,
|
|
1951
2612
|
isWritable: true,
|
|
1952
2613
|
});
|
|
1953
2614
|
|
|
1954
2615
|
const remainingAccounts = [
|
|
1955
2616
|
...oracleAccountMap.values(),
|
|
1956
|
-
...
|
|
2617
|
+
...spotMarketAccountMap.values(),
|
|
1957
2618
|
...marketAccountMap.values(),
|
|
1958
2619
|
];
|
|
1959
2620
|
|
|
1960
|
-
return await this.program.instruction.
|
|
2621
|
+
return await this.program.instruction.settleExpiredPosition(marketIndex, {
|
|
1961
2622
|
accounts: {
|
|
1962
2623
|
state: await this.getStatePublicKey(),
|
|
1963
2624
|
authority: this.wallet.publicKey,
|
|
@@ -1973,7 +2634,7 @@ export class ClearingHouse {
|
|
|
1973
2634
|
marketIndex: BN,
|
|
1974
2635
|
maxBaseAssetAmount: BN
|
|
1975
2636
|
): Promise<TransactionSignature> {
|
|
1976
|
-
const { txSig } = await this.txSender.send(
|
|
2637
|
+
const { txSig, slot } = await this.txSender.send(
|
|
1977
2638
|
wrapInTx(
|
|
1978
2639
|
await this.getLiquidatePerpIx(
|
|
1979
2640
|
userAccountPublicKey,
|
|
@@ -1985,6 +2646,7 @@ export class ClearingHouse {
|
|
|
1985
2646
|
[],
|
|
1986
2647
|
this.opts
|
|
1987
2648
|
);
|
|
2649
|
+
this.marketLastSlotCache.set(marketIndex.toNumber(), slot);
|
|
1988
2650
|
return txSig;
|
|
1989
2651
|
}
|
|
1990
2652
|
|
|
@@ -2003,7 +2665,7 @@ export class ClearingHouse {
|
|
|
2003
2665
|
const liquidatorStatsPublicKey = this.getUserStatsAccountPublicKey();
|
|
2004
2666
|
|
|
2005
2667
|
const remainingAccounts = this.getRemainingAccountsWithCounterparty({
|
|
2006
|
-
|
|
2668
|
+
writablePerpMarketIndex: marketIndex,
|
|
2007
2669
|
counterPartyUserAccount: userAccount,
|
|
2008
2670
|
});
|
|
2009
2671
|
|
|
@@ -2027,8 +2689,8 @@ export class ClearingHouse {
|
|
|
2027
2689
|
public async liquidateBorrow(
|
|
2028
2690
|
userAccountPublicKey: PublicKey,
|
|
2029
2691
|
userAccount: UserAccount,
|
|
2030
|
-
|
|
2031
|
-
|
|
2692
|
+
assetmarketIndex: BN,
|
|
2693
|
+
liabilitymarketIndex: BN,
|
|
2032
2694
|
maxLiabilityTransfer: BN
|
|
2033
2695
|
): Promise<TransactionSignature> {
|
|
2034
2696
|
const { txSig } = await this.txSender.send(
|
|
@@ -2036,8 +2698,8 @@ export class ClearingHouse {
|
|
|
2036
2698
|
await this.getLiquidateBorrowIx(
|
|
2037
2699
|
userAccountPublicKey,
|
|
2038
2700
|
userAccount,
|
|
2039
|
-
|
|
2040
|
-
|
|
2701
|
+
assetmarketIndex,
|
|
2702
|
+
liabilitymarketIndex,
|
|
2041
2703
|
maxLiabilityTransfer
|
|
2042
2704
|
)
|
|
2043
2705
|
),
|
|
@@ -2050,20 +2712,20 @@ export class ClearingHouse {
|
|
|
2050
2712
|
public async getLiquidateBorrowIx(
|
|
2051
2713
|
userAccountPublicKey: PublicKey,
|
|
2052
2714
|
userAccount: UserAccount,
|
|
2053
|
-
|
|
2054
|
-
|
|
2715
|
+
assetmarketIndex: BN,
|
|
2716
|
+
liabilitymarketIndex: BN,
|
|
2055
2717
|
maxLiabilityTransfer: BN
|
|
2056
2718
|
): Promise<TransactionInstruction> {
|
|
2057
2719
|
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
2058
2720
|
|
|
2059
2721
|
const remainingAccounts = this.getRemainingAccountsWithCounterparty({
|
|
2060
2722
|
counterPartyUserAccount: userAccount,
|
|
2061
|
-
|
|
2723
|
+
writableSpotMarketIndexes: [liabilitymarketIndex, assetmarketIndex],
|
|
2062
2724
|
});
|
|
2063
2725
|
|
|
2064
2726
|
return await this.program.instruction.liquidateBorrow(
|
|
2065
|
-
|
|
2066
|
-
|
|
2727
|
+
assetmarketIndex,
|
|
2728
|
+
liabilitymarketIndex,
|
|
2067
2729
|
maxLiabilityTransfer,
|
|
2068
2730
|
{
|
|
2069
2731
|
accounts: {
|
|
@@ -2081,22 +2743,23 @@ export class ClearingHouse {
|
|
|
2081
2743
|
userAccountPublicKey: PublicKey,
|
|
2082
2744
|
userAccount: UserAccount,
|
|
2083
2745
|
perpMarketIndex: BN,
|
|
2084
|
-
|
|
2746
|
+
liabilitymarketIndex: BN,
|
|
2085
2747
|
maxLiabilityTransfer: BN
|
|
2086
2748
|
): Promise<TransactionSignature> {
|
|
2087
|
-
const { txSig } = await this.txSender.send(
|
|
2749
|
+
const { txSig, slot } = await this.txSender.send(
|
|
2088
2750
|
wrapInTx(
|
|
2089
2751
|
await this.getLiquidateBorrowForPerpPnlIx(
|
|
2090
2752
|
userAccountPublicKey,
|
|
2091
2753
|
userAccount,
|
|
2092
2754
|
perpMarketIndex,
|
|
2093
|
-
|
|
2755
|
+
liabilitymarketIndex,
|
|
2094
2756
|
maxLiabilityTransfer
|
|
2095
2757
|
)
|
|
2096
2758
|
),
|
|
2097
2759
|
[],
|
|
2098
2760
|
this.opts
|
|
2099
2761
|
);
|
|
2762
|
+
this.marketLastSlotCache.set(perpMarketIndex.toNumber(), slot);
|
|
2100
2763
|
return txSig;
|
|
2101
2764
|
}
|
|
2102
2765
|
|
|
@@ -2104,20 +2767,20 @@ export class ClearingHouse {
|
|
|
2104
2767
|
userAccountPublicKey: PublicKey,
|
|
2105
2768
|
userAccount: UserAccount,
|
|
2106
2769
|
perpMarketIndex: BN,
|
|
2107
|
-
|
|
2770
|
+
liabilitymarketIndex: BN,
|
|
2108
2771
|
maxLiabilityTransfer: BN
|
|
2109
2772
|
): Promise<TransactionInstruction> {
|
|
2110
2773
|
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
2111
2774
|
|
|
2112
2775
|
const remainingAccounts = this.getRemainingAccountsWithCounterparty({
|
|
2113
2776
|
counterPartyUserAccount: userAccount,
|
|
2114
|
-
|
|
2115
|
-
|
|
2777
|
+
writablePerpMarketIndex: perpMarketIndex,
|
|
2778
|
+
writableSpotMarketIndexes: [liabilitymarketIndex],
|
|
2116
2779
|
});
|
|
2117
2780
|
|
|
2118
2781
|
return await this.program.instruction.liquidateBorrowForPerpPnl(
|
|
2119
2782
|
perpMarketIndex,
|
|
2120
|
-
|
|
2783
|
+
liabilitymarketIndex,
|
|
2121
2784
|
maxLiabilityTransfer,
|
|
2122
2785
|
{
|
|
2123
2786
|
accounts: {
|
|
@@ -2135,22 +2798,23 @@ export class ClearingHouse {
|
|
|
2135
2798
|
userAccountPublicKey: PublicKey,
|
|
2136
2799
|
userAccount: UserAccount,
|
|
2137
2800
|
perpMarketIndex: BN,
|
|
2138
|
-
|
|
2801
|
+
assetMarketIndex: BN,
|
|
2139
2802
|
maxPnlTransfer: BN
|
|
2140
2803
|
): Promise<TransactionSignature> {
|
|
2141
|
-
const { txSig } = await this.txSender.send(
|
|
2804
|
+
const { txSig, slot } = await this.txSender.send(
|
|
2142
2805
|
wrapInTx(
|
|
2143
2806
|
await this.getLiquidatePerpPnlForDepositIx(
|
|
2144
2807
|
userAccountPublicKey,
|
|
2145
2808
|
userAccount,
|
|
2146
2809
|
perpMarketIndex,
|
|
2147
|
-
|
|
2810
|
+
assetMarketIndex,
|
|
2148
2811
|
maxPnlTransfer
|
|
2149
2812
|
)
|
|
2150
2813
|
),
|
|
2151
2814
|
[],
|
|
2152
2815
|
this.opts
|
|
2153
2816
|
);
|
|
2817
|
+
this.marketLastSlotCache.set(perpMarketIndex.toNumber(), slot);
|
|
2154
2818
|
return txSig;
|
|
2155
2819
|
}
|
|
2156
2820
|
|
|
@@ -2158,20 +2822,20 @@ export class ClearingHouse {
|
|
|
2158
2822
|
userAccountPublicKey: PublicKey,
|
|
2159
2823
|
userAccount: UserAccount,
|
|
2160
2824
|
perpMarketIndex: BN,
|
|
2161
|
-
|
|
2825
|
+
assetMarketIndex: BN,
|
|
2162
2826
|
maxPnlTransfer: BN
|
|
2163
2827
|
): Promise<TransactionInstruction> {
|
|
2164
2828
|
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
2165
2829
|
|
|
2166
2830
|
const remainingAccounts = this.getRemainingAccountsWithCounterparty({
|
|
2167
2831
|
counterPartyUserAccount: userAccount,
|
|
2168
|
-
|
|
2169
|
-
|
|
2832
|
+
writablePerpMarketIndex: perpMarketIndex,
|
|
2833
|
+
writableSpotMarketIndexes: [assetMarketIndex],
|
|
2170
2834
|
});
|
|
2171
2835
|
|
|
2172
2836
|
return await this.program.instruction.liquidatePerpPnlForDeposit(
|
|
2173
2837
|
perpMarketIndex,
|
|
2174
|
-
|
|
2838
|
+
assetMarketIndex,
|
|
2175
2839
|
maxPnlTransfer,
|
|
2176
2840
|
{
|
|
2177
2841
|
accounts: {
|
|
@@ -2188,7 +2852,6 @@ export class ClearingHouse {
|
|
|
2188
2852
|
public async resolvePerpBankruptcy(
|
|
2189
2853
|
userAccountPublicKey: PublicKey,
|
|
2190
2854
|
userAccount: UserAccount,
|
|
2191
|
-
bankIndex: BN,
|
|
2192
2855
|
marketIndex: BN
|
|
2193
2856
|
): Promise<TransactionSignature> {
|
|
2194
2857
|
const { txSig } = await this.txSender.send(
|
|
@@ -2196,7 +2859,6 @@ export class ClearingHouse {
|
|
|
2196
2859
|
await this.getResolvePerpBankruptcyIx(
|
|
2197
2860
|
userAccountPublicKey,
|
|
2198
2861
|
userAccount,
|
|
2199
|
-
bankIndex,
|
|
2200
2862
|
marketIndex
|
|
2201
2863
|
)
|
|
2202
2864
|
),
|
|
@@ -2209,21 +2871,20 @@ export class ClearingHouse {
|
|
|
2209
2871
|
public async getResolvePerpBankruptcyIx(
|
|
2210
2872
|
userAccountPublicKey: PublicKey,
|
|
2211
2873
|
userAccount: UserAccount,
|
|
2212
|
-
bankIndex: BN,
|
|
2213
2874
|
marketIndex: BN
|
|
2214
2875
|
): Promise<TransactionInstruction> {
|
|
2215
2876
|
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
2216
2877
|
|
|
2217
2878
|
const remainingAccounts = this.getRemainingAccountsWithCounterparty({
|
|
2218
|
-
|
|
2219
|
-
|
|
2879
|
+
writablePerpMarketIndex: marketIndex,
|
|
2880
|
+
writableSpotMarketIndexes: [QUOTE_SPOT_MARKET_INDEX],
|
|
2220
2881
|
counterPartyUserAccount: userAccount,
|
|
2221
2882
|
});
|
|
2222
2883
|
|
|
2223
|
-
const
|
|
2884
|
+
const spotMarket = this.getSpotMarketAccount(marketIndex);
|
|
2224
2885
|
|
|
2225
2886
|
return await this.program.instruction.resolvePerpBankruptcy(
|
|
2226
|
-
|
|
2887
|
+
QUOTE_SPOT_MARKET_INDEX,
|
|
2227
2888
|
marketIndex,
|
|
2228
2889
|
{
|
|
2229
2890
|
accounts: {
|
|
@@ -2231,8 +2892,8 @@ export class ClearingHouse {
|
|
|
2231
2892
|
authority: this.wallet.publicKey,
|
|
2232
2893
|
user: userAccountPublicKey,
|
|
2233
2894
|
liquidator: liquidatorPublicKey,
|
|
2234
|
-
|
|
2235
|
-
insuranceFundVault:
|
|
2895
|
+
spotMarketVault: spotMarket.vault,
|
|
2896
|
+
insuranceFundVault: spotMarket.insuranceFundVault,
|
|
2236
2897
|
clearingHouseSigner: this.getSignerPublicKey(),
|
|
2237
2898
|
tokenProgram: TOKEN_PROGRAM_ID,
|
|
2238
2899
|
},
|
|
@@ -2244,14 +2905,14 @@ export class ClearingHouse {
|
|
|
2244
2905
|
public async resolveBorrowBankruptcy(
|
|
2245
2906
|
userAccountPublicKey: PublicKey,
|
|
2246
2907
|
userAccount: UserAccount,
|
|
2247
|
-
|
|
2908
|
+
marketIndex: BN
|
|
2248
2909
|
): Promise<TransactionSignature> {
|
|
2249
2910
|
const { txSig } = await this.txSender.send(
|
|
2250
2911
|
wrapInTx(
|
|
2251
2912
|
await this.getResolveBorrowBankruptcyIx(
|
|
2252
2913
|
userAccountPublicKey,
|
|
2253
2914
|
userAccount,
|
|
2254
|
-
|
|
2915
|
+
marketIndex
|
|
2255
2916
|
)
|
|
2256
2917
|
),
|
|
2257
2918
|
[],
|
|
@@ -2263,25 +2924,25 @@ export class ClearingHouse {
|
|
|
2263
2924
|
public async getResolveBorrowBankruptcyIx(
|
|
2264
2925
|
userAccountPublicKey: PublicKey,
|
|
2265
2926
|
userAccount: UserAccount,
|
|
2266
|
-
|
|
2927
|
+
marketIndex: BN
|
|
2267
2928
|
): Promise<TransactionInstruction> {
|
|
2268
2929
|
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
2269
2930
|
|
|
2270
2931
|
const remainingAccounts = this.getRemainingAccountsWithCounterparty({
|
|
2271
|
-
|
|
2932
|
+
writableSpotMarketIndexes: [marketIndex],
|
|
2272
2933
|
counterPartyUserAccount: userAccount,
|
|
2273
2934
|
});
|
|
2274
2935
|
|
|
2275
|
-
const
|
|
2936
|
+
const spotMarket = this.getSpotMarketAccount(marketIndex);
|
|
2276
2937
|
|
|
2277
|
-
return await this.program.instruction.resolveBorrowBankruptcy(
|
|
2938
|
+
return await this.program.instruction.resolveBorrowBankruptcy(marketIndex, {
|
|
2278
2939
|
accounts: {
|
|
2279
2940
|
state: await this.getStatePublicKey(),
|
|
2280
2941
|
authority: this.wallet.publicKey,
|
|
2281
2942
|
user: userAccountPublicKey,
|
|
2282
2943
|
liquidator: liquidatorPublicKey,
|
|
2283
|
-
|
|
2284
|
-
insuranceFundVault:
|
|
2944
|
+
spotMarketVault: spotMarket.vault,
|
|
2945
|
+
insuranceFundVault: spotMarket.insuranceFundVault,
|
|
2285
2946
|
clearingHouseSigner: this.getSignerPublicKey(),
|
|
2286
2947
|
tokenProgram: TOKEN_PROGRAM_ID,
|
|
2287
2948
|
},
|
|
@@ -2291,35 +2952,35 @@ export class ClearingHouse {
|
|
|
2291
2952
|
|
|
2292
2953
|
getRemainingAccountsWithCounterparty(params: {
|
|
2293
2954
|
counterPartyUserAccount: UserAccount;
|
|
2294
|
-
|
|
2295
|
-
|
|
2955
|
+
writablePerpMarketIndex?: BN;
|
|
2956
|
+
writableSpotMarketIndexes?: BN[];
|
|
2296
2957
|
}): AccountMeta[] {
|
|
2297
2958
|
const counterPartyUserAccount = params.counterPartyUserAccount;
|
|
2298
2959
|
|
|
2299
2960
|
const oracleAccountMap = new Map<string, AccountMeta>();
|
|
2300
|
-
const
|
|
2961
|
+
const spotMarketAccountMap = new Map<number, AccountMeta>();
|
|
2301
2962
|
const marketAccountMap = new Map<number, AccountMeta>();
|
|
2302
|
-
for (const
|
|
2303
|
-
if (!
|
|
2304
|
-
const
|
|
2305
|
-
|
|
2306
|
-
pubkey:
|
|
2963
|
+
for (const spotPosition of counterPartyUserAccount.spotPositions) {
|
|
2964
|
+
if (!isSpotPositionAvailable(spotPosition)) {
|
|
2965
|
+
const spotMarket = this.getSpotMarketAccount(spotPosition.marketIndex);
|
|
2966
|
+
spotMarketAccountMap.set(spotPosition.marketIndex.toNumber(), {
|
|
2967
|
+
pubkey: spotMarket.pubkey,
|
|
2307
2968
|
isSigner: false,
|
|
2308
2969
|
isWritable: false,
|
|
2309
2970
|
});
|
|
2310
2971
|
|
|
2311
|
-
if (!
|
|
2312
|
-
oracleAccountMap.set(
|
|
2313
|
-
pubkey:
|
|
2972
|
+
if (!spotMarket.oracle.equals(PublicKey.default)) {
|
|
2973
|
+
oracleAccountMap.set(spotMarket.oracle.toString(), {
|
|
2974
|
+
pubkey: spotMarket.oracle,
|
|
2314
2975
|
isSigner: false,
|
|
2315
2976
|
isWritable: false,
|
|
2316
2977
|
});
|
|
2317
2978
|
}
|
|
2318
2979
|
}
|
|
2319
2980
|
}
|
|
2320
|
-
for (const position of counterPartyUserAccount.
|
|
2981
|
+
for (const position of counterPartyUserAccount.perpPositions) {
|
|
2321
2982
|
if (!positionIsAvailable(position)) {
|
|
2322
|
-
const market = this.
|
|
2983
|
+
const market = this.getPerpMarketAccount(position.marketIndex);
|
|
2323
2984
|
marketAccountMap.set(position.marketIndex.toNumber(), {
|
|
2324
2985
|
pubkey: market.pubkey,
|
|
2325
2986
|
isWritable: false,
|
|
@@ -2346,7 +3007,7 @@ export class ClearingHouse {
|
|
|
2346
3007
|
// if cache has more recent slot than user positions account slot, add market to remaining accounts
|
|
2347
3008
|
// otherwise remove from slot
|
|
2348
3009
|
if (slot > lastUserPositionsSlot) {
|
|
2349
|
-
const marketAccount = this.
|
|
3010
|
+
const marketAccount = this.getPerpMarketAccount(marketIndexNum);
|
|
2350
3011
|
marketAccountMap.set(marketIndexNum, {
|
|
2351
3012
|
pubkey: marketAccount.pubkey,
|
|
2352
3013
|
isSigner: false,
|
|
@@ -2361,27 +3022,27 @@ export class ClearingHouse {
|
|
|
2361
3022
|
this.marketLastSlotCache.delete(marketIndexNum);
|
|
2362
3023
|
}
|
|
2363
3024
|
}
|
|
2364
|
-
for (const
|
|
2365
|
-
if (!
|
|
2366
|
-
const
|
|
2367
|
-
|
|
2368
|
-
pubkey:
|
|
3025
|
+
for (const spotPosition of userAccount.spotPositions) {
|
|
3026
|
+
if (!isSpotPositionAvailable(spotPosition)) {
|
|
3027
|
+
const spotMarket = this.getSpotMarketAccount(spotPosition.marketIndex);
|
|
3028
|
+
spotMarketAccountMap.set(spotPosition.marketIndex.toNumber(), {
|
|
3029
|
+
pubkey: spotMarket.pubkey,
|
|
2369
3030
|
isSigner: false,
|
|
2370
3031
|
isWritable: false,
|
|
2371
3032
|
});
|
|
2372
3033
|
|
|
2373
|
-
if (!
|
|
2374
|
-
oracleAccountMap.set(
|
|
2375
|
-
pubkey:
|
|
3034
|
+
if (!spotMarket.oracle.equals(PublicKey.default)) {
|
|
3035
|
+
oracleAccountMap.set(spotMarket.oracle.toString(), {
|
|
3036
|
+
pubkey: spotMarket.oracle,
|
|
2376
3037
|
isSigner: false,
|
|
2377
3038
|
isWritable: false,
|
|
2378
3039
|
});
|
|
2379
3040
|
}
|
|
2380
3041
|
}
|
|
2381
3042
|
}
|
|
2382
|
-
for (const position of userAccount.
|
|
3043
|
+
for (const position of userAccount.perpPositions) {
|
|
2383
3044
|
if (!positionIsAvailable(position)) {
|
|
2384
|
-
const market = this.
|
|
3045
|
+
const market = this.getPerpMarketAccount(position.marketIndex);
|
|
2385
3046
|
marketAccountMap.set(position.marketIndex.toNumber(), {
|
|
2386
3047
|
pubkey: market.pubkey,
|
|
2387
3048
|
isWritable: false,
|
|
@@ -2395,8 +3056,8 @@ export class ClearingHouse {
|
|
|
2395
3056
|
}
|
|
2396
3057
|
}
|
|
2397
3058
|
|
|
2398
|
-
if (params.
|
|
2399
|
-
const market = this.
|
|
3059
|
+
if (params.writablePerpMarketIndex) {
|
|
3060
|
+
const market = this.getPerpMarketAccount(params.writablePerpMarketIndex);
|
|
2400
3061
|
marketAccountMap.set(market.marketIndex.toNumber(), {
|
|
2401
3062
|
pubkey: market.pubkey,
|
|
2402
3063
|
isSigner: false,
|
|
@@ -2409,17 +3070,19 @@ export class ClearingHouse {
|
|
|
2409
3070
|
});
|
|
2410
3071
|
}
|
|
2411
3072
|
|
|
2412
|
-
if (params.
|
|
2413
|
-
for (const
|
|
2414
|
-
const
|
|
2415
|
-
|
|
2416
|
-
|
|
3073
|
+
if (params.writableSpotMarketIndexes) {
|
|
3074
|
+
for (const writableSpotMarketIndex of params.writableSpotMarketIndexes) {
|
|
3075
|
+
const spotMarketAccount = this.getSpotMarketAccount(
|
|
3076
|
+
writableSpotMarketIndex
|
|
3077
|
+
);
|
|
3078
|
+
spotMarketAccountMap.set(spotMarketAccount.marketIndex.toNumber(), {
|
|
3079
|
+
pubkey: spotMarketAccount.pubkey,
|
|
2417
3080
|
isSigner: false,
|
|
2418
3081
|
isWritable: true,
|
|
2419
3082
|
});
|
|
2420
|
-
if (!
|
|
2421
|
-
oracleAccountMap.set(
|
|
2422
|
-
pubkey:
|
|
3083
|
+
if (!spotMarketAccount.oracle.equals(PublicKey.default)) {
|
|
3084
|
+
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
3085
|
+
pubkey: spotMarketAccount.oracle,
|
|
2423
3086
|
isSigner: false,
|
|
2424
3087
|
isWritable: false,
|
|
2425
3088
|
});
|
|
@@ -2429,7 +3092,7 @@ export class ClearingHouse {
|
|
|
2429
3092
|
|
|
2430
3093
|
return [
|
|
2431
3094
|
...oracleAccountMap.values(),
|
|
2432
|
-
...
|
|
3095
|
+
...spotMarketAccountMap.values(),
|
|
2433
3096
|
...marketAccountMap.values(),
|
|
2434
3097
|
];
|
|
2435
3098
|
}
|
|
@@ -2477,7 +3140,7 @@ export class ClearingHouse {
|
|
|
2477
3140
|
userAccount
|
|
2478
3141
|
)) as UserAccount;
|
|
2479
3142
|
|
|
2480
|
-
const userPositions = user.
|
|
3143
|
+
const userPositions = user.perpPositions;
|
|
2481
3144
|
|
|
2482
3145
|
const remainingAccounts = [];
|
|
2483
3146
|
for (const position of userPositions) {
|
|
@@ -2508,17 +3171,17 @@ export class ClearingHouse {
|
|
|
2508
3171
|
}
|
|
2509
3172
|
|
|
2510
3173
|
public getOracleDataForMarket(marketIndex: BN): OraclePriceData {
|
|
2511
|
-
const oracleKey = this.
|
|
3174
|
+
const oracleKey = this.getPerpMarketAccount(marketIndex).amm.oracle;
|
|
2512
3175
|
const oracleData = this.getOraclePriceDataAndSlot(oracleKey).data;
|
|
2513
3176
|
|
|
2514
3177
|
return oracleData;
|
|
2515
3178
|
}
|
|
2516
3179
|
|
|
2517
3180
|
public async initializeInsuranceFundStake(
|
|
2518
|
-
|
|
3181
|
+
marketIndex: BN
|
|
2519
3182
|
): Promise<TransactionSignature> {
|
|
2520
3183
|
const { txSig } = await this.txSender.send(
|
|
2521
|
-
wrapInTx(await this.getInitializeInsuranceFundStakeIx(
|
|
3184
|
+
wrapInTx(await this.getInitializeInsuranceFundStakeIx(marketIndex)),
|
|
2522
3185
|
[],
|
|
2523
3186
|
this.opts
|
|
2524
3187
|
);
|
|
@@ -2526,20 +3189,20 @@ export class ClearingHouse {
|
|
|
2526
3189
|
}
|
|
2527
3190
|
|
|
2528
3191
|
public async getInitializeInsuranceFundStakeIx(
|
|
2529
|
-
|
|
3192
|
+
marketIndex: BN
|
|
2530
3193
|
): Promise<TransactionInstruction> {
|
|
2531
3194
|
const ifStakeAccountPublicKey = getInsuranceFundStakeAccountPublicKey(
|
|
2532
3195
|
this.program.programId,
|
|
2533
3196
|
this.wallet.publicKey,
|
|
2534
|
-
|
|
3197
|
+
marketIndex
|
|
2535
3198
|
);
|
|
2536
3199
|
|
|
2537
3200
|
return await this.program.instruction.initializeInsuranceFundStake(
|
|
2538
|
-
|
|
3201
|
+
marketIndex,
|
|
2539
3202
|
{
|
|
2540
3203
|
accounts: {
|
|
2541
3204
|
insuranceFundStake: ifStakeAccountPublicKey,
|
|
2542
|
-
|
|
3205
|
+
spotMarket: this.getSpotMarketAccount(marketIndex).pubkey,
|
|
2543
3206
|
userStats: this.getUserStatsAccountPublicKey(),
|
|
2544
3207
|
authority: this.wallet.publicKey,
|
|
2545
3208
|
payer: this.wallet.publicKey,
|
|
@@ -2552,29 +3215,29 @@ export class ClearingHouse {
|
|
|
2552
3215
|
}
|
|
2553
3216
|
|
|
2554
3217
|
public async addInsuranceFundStake(
|
|
2555
|
-
|
|
3218
|
+
marketIndex: BN,
|
|
2556
3219
|
amount: BN,
|
|
2557
3220
|
collateralAccountPublicKey: PublicKey
|
|
2558
3221
|
): Promise<TransactionSignature> {
|
|
2559
|
-
const
|
|
3222
|
+
const spotMarket = this.getSpotMarketAccount(marketIndex);
|
|
2560
3223
|
const ifStakeAccountPublicKey = getInsuranceFundStakeAccountPublicKey(
|
|
2561
3224
|
this.program.programId,
|
|
2562
3225
|
this.wallet.publicKey,
|
|
2563
|
-
|
|
3226
|
+
marketIndex
|
|
2564
3227
|
);
|
|
2565
3228
|
|
|
2566
3229
|
const remainingAccounts = this.getRemainingAccounts({
|
|
2567
|
-
|
|
3230
|
+
writableSpotMarketIndex: marketIndex,
|
|
2568
3231
|
});
|
|
2569
3232
|
|
|
2570
|
-
return await this.program.rpc.addInsuranceFundStake(
|
|
3233
|
+
return await this.program.rpc.addInsuranceFundStake(marketIndex, amount, {
|
|
2571
3234
|
accounts: {
|
|
2572
3235
|
state: await this.getStatePublicKey(),
|
|
2573
|
-
|
|
3236
|
+
spotMarket: spotMarket.pubkey,
|
|
2574
3237
|
insuranceFundStake: ifStakeAccountPublicKey,
|
|
2575
3238
|
userStats: this.getUserStatsAccountPublicKey(),
|
|
2576
3239
|
authority: this.wallet.publicKey,
|
|
2577
|
-
insuranceFundVault:
|
|
3240
|
+
insuranceFundVault: spotMarket.insuranceFundVault,
|
|
2578
3241
|
userTokenAccount: collateralAccountPublicKey,
|
|
2579
3242
|
tokenProgram: TOKEN_PROGRAM_ID,
|
|
2580
3243
|
},
|
|
@@ -2583,31 +3246,31 @@ export class ClearingHouse {
|
|
|
2583
3246
|
}
|
|
2584
3247
|
|
|
2585
3248
|
public async requestRemoveInsuranceFundStake(
|
|
2586
|
-
|
|
3249
|
+
marketIndex: BN,
|
|
2587
3250
|
amount: BN
|
|
2588
3251
|
): Promise<TransactionSignature> {
|
|
2589
|
-
const
|
|
3252
|
+
const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
|
|
2590
3253
|
const ifStakeAccountPublicKey = getInsuranceFundStakeAccountPublicKey(
|
|
2591
3254
|
this.program.programId,
|
|
2592
3255
|
this.wallet.publicKey,
|
|
2593
|
-
|
|
3256
|
+
marketIndex
|
|
2594
3257
|
);
|
|
2595
3258
|
|
|
2596
3259
|
const remainingAccounts = this.getRemainingAccounts({
|
|
2597
|
-
|
|
3260
|
+
writableSpotMarketIndex: marketIndex,
|
|
2598
3261
|
});
|
|
2599
3262
|
|
|
2600
3263
|
return await this.program.rpc.requestRemoveInsuranceFundStake(
|
|
2601
|
-
|
|
3264
|
+
marketIndex,
|
|
2602
3265
|
amount,
|
|
2603
3266
|
{
|
|
2604
3267
|
accounts: {
|
|
2605
3268
|
state: await this.getStatePublicKey(),
|
|
2606
|
-
|
|
3269
|
+
spotMarket: spotMarketAccount.pubkey,
|
|
2607
3270
|
insuranceFundStake: ifStakeAccountPublicKey,
|
|
2608
3271
|
userStats: this.getUserStatsAccountPublicKey(),
|
|
2609
3272
|
authority: this.wallet.publicKey,
|
|
2610
|
-
insuranceFundVault:
|
|
3273
|
+
insuranceFundVault: spotMarketAccount.insuranceFundVault,
|
|
2611
3274
|
// userTokenAccount: collateralAccountPublicKey,
|
|
2612
3275
|
// tokenProgram: TOKEN_PROGRAM_ID,
|
|
2613
3276
|
},
|
|
@@ -2617,29 +3280,29 @@ export class ClearingHouse {
|
|
|
2617
3280
|
}
|
|
2618
3281
|
|
|
2619
3282
|
public async cancelRequestRemoveInsuranceFundStake(
|
|
2620
|
-
|
|
3283
|
+
marketIndex: BN
|
|
2621
3284
|
): Promise<TransactionSignature> {
|
|
2622
|
-
const
|
|
3285
|
+
const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
|
|
2623
3286
|
const ifStakeAccountPublicKey = getInsuranceFundStakeAccountPublicKey(
|
|
2624
3287
|
this.program.programId,
|
|
2625
3288
|
this.wallet.publicKey,
|
|
2626
|
-
|
|
3289
|
+
marketIndex
|
|
2627
3290
|
);
|
|
2628
3291
|
|
|
2629
3292
|
const remainingAccounts = this.getRemainingAccounts({
|
|
2630
|
-
|
|
3293
|
+
writableSpotMarketIndex: marketIndex,
|
|
2631
3294
|
});
|
|
2632
3295
|
|
|
2633
3296
|
return await this.program.rpc.cancelRequestRemoveInsuranceFundStake(
|
|
2634
|
-
|
|
3297
|
+
marketIndex,
|
|
2635
3298
|
{
|
|
2636
3299
|
accounts: {
|
|
2637
3300
|
state: await this.getStatePublicKey(),
|
|
2638
|
-
|
|
3301
|
+
spotMarket: spotMarketAccount.pubkey,
|
|
2639
3302
|
insuranceFundStake: ifStakeAccountPublicKey,
|
|
2640
3303
|
userStats: this.getUserStatsAccountPublicKey(),
|
|
2641
3304
|
authority: this.wallet.publicKey,
|
|
2642
|
-
insuranceFundVault:
|
|
3305
|
+
insuranceFundVault: spotMarketAccount.insuranceFundVault,
|
|
2643
3306
|
// userTokenAccount: collateralAccountPublicKey,
|
|
2644
3307
|
// tokenProgram: TOKEN_PROGRAM_ID,
|
|
2645
3308
|
},
|
|
@@ -2649,28 +3312,28 @@ export class ClearingHouse {
|
|
|
2649
3312
|
}
|
|
2650
3313
|
|
|
2651
3314
|
public async removeInsuranceFundStake(
|
|
2652
|
-
|
|
3315
|
+
marketIndex: BN,
|
|
2653
3316
|
collateralAccountPublicKey: PublicKey
|
|
2654
3317
|
): Promise<TransactionSignature> {
|
|
2655
|
-
const
|
|
3318
|
+
const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
|
|
2656
3319
|
const ifStakeAccountPublicKey = getInsuranceFundStakeAccountPublicKey(
|
|
2657
3320
|
this.program.programId,
|
|
2658
3321
|
this.wallet.publicKey,
|
|
2659
|
-
|
|
3322
|
+
marketIndex
|
|
2660
3323
|
);
|
|
2661
3324
|
|
|
2662
3325
|
const remainingAccounts = this.getRemainingAccounts({
|
|
2663
|
-
|
|
3326
|
+
writableSpotMarketIndex: marketIndex,
|
|
2664
3327
|
});
|
|
2665
3328
|
|
|
2666
|
-
return await this.program.rpc.removeInsuranceFundStake(
|
|
3329
|
+
return await this.program.rpc.removeInsuranceFundStake(marketIndex, {
|
|
2667
3330
|
accounts: {
|
|
2668
3331
|
state: await this.getStatePublicKey(),
|
|
2669
|
-
|
|
3332
|
+
spotMarket: spotMarketAccount.pubkey,
|
|
2670
3333
|
insuranceFundStake: ifStakeAccountPublicKey,
|
|
2671
3334
|
userStats: this.getUserStatsAccountPublicKey(),
|
|
2672
3335
|
authority: this.wallet.publicKey,
|
|
2673
|
-
insuranceFundVault:
|
|
3336
|
+
insuranceFundVault: spotMarketAccount.insuranceFundVault,
|
|
2674
3337
|
clearingHouseSigner: this.getSignerPublicKey(),
|
|
2675
3338
|
userTokenAccount: collateralAccountPublicKey,
|
|
2676
3339
|
tokenProgram: TOKEN_PROGRAM_ID,
|
|
@@ -2680,24 +3343,66 @@ export class ClearingHouse {
|
|
|
2680
3343
|
}
|
|
2681
3344
|
|
|
2682
3345
|
public async settleRevenueToInsuranceFund(
|
|
2683
|
-
|
|
3346
|
+
marketIndex: BN
|
|
2684
3347
|
): Promise<TransactionSignature> {
|
|
2685
|
-
const
|
|
3348
|
+
const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
|
|
2686
3349
|
|
|
2687
3350
|
const remainingAccounts = this.getRemainingAccounts({
|
|
2688
|
-
|
|
3351
|
+
writableSpotMarketIndex: marketIndex,
|
|
2689
3352
|
});
|
|
2690
3353
|
|
|
2691
|
-
return await this.program.rpc.settleRevenueToInsuranceFund(
|
|
3354
|
+
return await this.program.rpc.settleRevenueToInsuranceFund(marketIndex, {
|
|
2692
3355
|
accounts: {
|
|
2693
3356
|
state: await this.getStatePublicKey(),
|
|
2694
|
-
|
|
2695
|
-
|
|
3357
|
+
spotMarket: spotMarketAccount.pubkey,
|
|
3358
|
+
spotMarketVault: spotMarketAccount.vault,
|
|
2696
3359
|
clearingHouseSigner: this.getSignerPublicKey(),
|
|
2697
|
-
insuranceFundVault:
|
|
3360
|
+
insuranceFundVault: spotMarketAccount.insuranceFundVault,
|
|
2698
3361
|
tokenProgram: TOKEN_PROGRAM_ID,
|
|
2699
3362
|
},
|
|
2700
3363
|
remainingAccounts,
|
|
2701
3364
|
});
|
|
2702
3365
|
}
|
|
3366
|
+
|
|
3367
|
+
public async resolvePerpPnlDeficit(
|
|
3368
|
+
spotMarketIndex: BN,
|
|
3369
|
+
perpMarketIndex: BN
|
|
3370
|
+
): Promise<TransactionSignature> {
|
|
3371
|
+
const { txSig } = await this.txSender.send(
|
|
3372
|
+
wrapInTx(
|
|
3373
|
+
await this.getResolvePerpPnlDeficitIx(spotMarketIndex, perpMarketIndex)
|
|
3374
|
+
),
|
|
3375
|
+
[],
|
|
3376
|
+
this.opts
|
|
3377
|
+
);
|
|
3378
|
+
return txSig;
|
|
3379
|
+
}
|
|
3380
|
+
|
|
3381
|
+
public async getResolvePerpPnlDeficitIx(
|
|
3382
|
+
spotMarketIndex: BN,
|
|
3383
|
+
perpMarketIndex: BN
|
|
3384
|
+
): Promise<TransactionInstruction> {
|
|
3385
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
3386
|
+
writablePerpMarketIndex: perpMarketIndex,
|
|
3387
|
+
writableSpotMarketIndex: spotMarketIndex,
|
|
3388
|
+
});
|
|
3389
|
+
|
|
3390
|
+
const spotMarket = this.getSpotMarketAccount(spotMarketIndex);
|
|
3391
|
+
|
|
3392
|
+
return await this.program.instruction.resolvePerpPnlDeficit(
|
|
3393
|
+
spotMarketIndex,
|
|
3394
|
+
perpMarketIndex,
|
|
3395
|
+
{
|
|
3396
|
+
accounts: {
|
|
3397
|
+
state: await this.getStatePublicKey(),
|
|
3398
|
+
authority: this.wallet.publicKey,
|
|
3399
|
+
spotMarketVault: spotMarket.vault,
|
|
3400
|
+
insuranceFundVault: spotMarket.insuranceFundVault,
|
|
3401
|
+
clearingHouseSigner: this.getSignerPublicKey(),
|
|
3402
|
+
tokenProgram: TOKEN_PROGRAM_ID,
|
|
3403
|
+
},
|
|
3404
|
+
remainingAccounts: remainingAccounts,
|
|
3405
|
+
}
|
|
3406
|
+
);
|
|
3407
|
+
}
|
|
2703
3408
|
}
|