@drift-labs/sdk 0.2.0-master.30 → 0.2.0-master.32
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/admin.d.ts +11 -7
- package/lib/admin.js +50 -12
- package/lib/clearingHouse.d.ts +26 -23
- package/lib/clearingHouse.js +290 -652
- package/lib/clearingHouseUser.d.ts +1 -1
- package/lib/clearingHouseUser.js +9 -12
- package/lib/config.js +1 -1
- package/lib/constants/numericConstants.d.ts +7 -0
- package/lib/constants/numericConstants.js +8 -1
- package/lib/constants/spotMarkets.js +4 -4
- package/lib/dlob/DLOB.d.ts +7 -5
- package/lib/dlob/DLOB.js +159 -88
- package/lib/dlob/DLOBNode.d.ts +2 -0
- package/lib/dlob/DLOBNode.js +3 -0
- package/lib/dlob/NodeList.d.ts +2 -1
- package/lib/dlob/NodeList.js +10 -4
- package/lib/events/types.d.ts +2 -1
- package/lib/events/types.js +1 -0
- package/lib/factory/bigNum.d.ts +1 -0
- package/lib/factory/bigNum.js +14 -0
- package/lib/idl/clearing_house.json +1091 -611
- package/lib/math/amm.d.ts +2 -2
- package/lib/math/amm.js +31 -28
- package/lib/math/market.d.ts +1 -1
- package/lib/math/market.js +6 -6
- package/lib/math/spotBalance.js +7 -8
- package/lib/math/trade.js +11 -11
- package/lib/types.d.ts +118 -41
- package/lib/types.js +34 -4
- package/package.json +4 -2
- package/src/admin.ts +129 -29
- package/src/clearingHouse.ts +380 -787
- package/src/clearingHouseUser.ts +11 -14
- package/src/config.ts +1 -1
- package/src/constants/numericConstants.ts +7 -0
- package/src/constants/spotMarkets.ts +5 -4
- package/src/dlob/DLOB.ts +221 -103
- package/src/dlob/DLOBNode.ts +5 -0
- package/src/dlob/NodeList.ts +15 -5
- package/src/events/types.ts +3 -0
- package/src/factory/bigNum.ts +23 -0
- package/src/idl/clearing_house.json +1091 -611
- package/src/math/amm.ts +42 -29
- package/src/math/market.ts +9 -4
- package/src/math/spotBalance.ts +11 -8
- package/src/math/trade.ts +11 -11
- package/src/types.ts +82 -41
- package/tests/bn/test.ts +13 -8
- package/tests/dlob/helpers.ts +56 -33
- package/tests/dlob/test.ts +1397 -495
- package/src/assert/assert.js +0 -9
- package/src/events/eventList.js +0 -77
- package/src/examples/makeTradeExample.js +0 -157
- package/src/token/index.js +0 -38
- package/src/tx/types.js +0 -2
- package/src/tx/utils.js +0 -17
- package/src/util/computeUnits.js +0 -27
- package/src/util/getTokenAddress.js +0 -9
- package/src/util/promiseTimeout.js +0 -14
- package/src/util/tps.js +0 -27
package/src/clearingHouse.ts
CHANGED
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
ReferrerInfo,
|
|
24
24
|
MarketType,
|
|
25
25
|
SerumV3FulfillmentConfigAccount,
|
|
26
|
+
isVariant,
|
|
26
27
|
} from './types';
|
|
27
28
|
import * as anchor from '@project-serum/anchor';
|
|
28
29
|
import clearingHouseIDL from './idl/clearing_house.json';
|
|
@@ -63,11 +64,7 @@ import {
|
|
|
63
64
|
} from './accounts/types';
|
|
64
65
|
import { TxSender } from './tx/types';
|
|
65
66
|
import { wrapInTx } from './tx/utils';
|
|
66
|
-
import {
|
|
67
|
-
ONE,
|
|
68
|
-
QUOTE_SPOT_MARKET_INDEX,
|
|
69
|
-
ZERO,
|
|
70
|
-
} from './constants/numericConstants';
|
|
67
|
+
import { QUOTE_SPOT_MARKET_INDEX } from './constants/numericConstants';
|
|
71
68
|
import { findDirectionToClose, positionIsAvailable } from './math/position';
|
|
72
69
|
import { getTokenAmount } from './math/spotBalance';
|
|
73
70
|
import { DEFAULT_USER_NAME, encodeName } from './userName';
|
|
@@ -83,6 +80,15 @@ import { WRAPPED_SOL_MINT } from './constants/spotMarkets';
|
|
|
83
80
|
import { ClearingHouseUserStats } from './clearingHouseUserStats';
|
|
84
81
|
import { isSpotPositionAvailable } from './math/spotPosition';
|
|
85
82
|
|
|
83
|
+
type RemainingAccountParams = {
|
|
84
|
+
userAccounts: UserAccount[];
|
|
85
|
+
writablePerpMarketIndexes?: number[];
|
|
86
|
+
writableSpotMarketIndexes?: number[];
|
|
87
|
+
readablePerpMarketIndex?: number;
|
|
88
|
+
readableSpotMarketIndex?: number;
|
|
89
|
+
useMarketLastSlotCache?: boolean;
|
|
90
|
+
};
|
|
91
|
+
|
|
86
92
|
/**
|
|
87
93
|
* # ClearingHouse
|
|
88
94
|
* This class is the main way to interact with Drift Protocol. It allows you to subscribe to the various accounts where the Market's state is stored, as well as: opening positions, liquidating, settling funding, depositing & withdrawing, and more.
|
|
@@ -440,6 +446,21 @@ export class ClearingHouse {
|
|
|
440
446
|
});
|
|
441
447
|
}
|
|
442
448
|
|
|
449
|
+
const state = this.getStateAccount();
|
|
450
|
+
if (!state.whitelistMint.equals(PublicKey.default)) {
|
|
451
|
+
const associatedTokenPublicKey = await Token.getAssociatedTokenAddress(
|
|
452
|
+
ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
453
|
+
TOKEN_PROGRAM_ID,
|
|
454
|
+
state.whitelistMint,
|
|
455
|
+
this.wallet.publicKey
|
|
456
|
+
);
|
|
457
|
+
remainingAccounts.push({
|
|
458
|
+
pubkey: associatedTokenPublicKey,
|
|
459
|
+
isWritable: false,
|
|
460
|
+
isSigner: false,
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
|
|
443
464
|
const nameBuffer = encodeName(name);
|
|
444
465
|
const initializeUserAccountIx =
|
|
445
466
|
await this.program.instruction.initializeUser(userId, nameBuffer, {
|
|
@@ -530,6 +551,28 @@ export class ClearingHouse {
|
|
|
530
551
|
);
|
|
531
552
|
}
|
|
532
553
|
|
|
554
|
+
public async deleteUser(userId = 0): Promise<TransactionSignature> {
|
|
555
|
+
const userAccountPublicKey = getUserAccountPublicKeySync(
|
|
556
|
+
this.program.programId,
|
|
557
|
+
this.wallet.publicKey,
|
|
558
|
+
userId
|
|
559
|
+
);
|
|
560
|
+
|
|
561
|
+
const txSig = await this.program.rpc.deleteUser({
|
|
562
|
+
accounts: {
|
|
563
|
+
user: userAccountPublicKey,
|
|
564
|
+
userStats: this.getUserStatsAccountPublicKey(),
|
|
565
|
+
authority: this.wallet.publicKey,
|
|
566
|
+
state: await this.getStatePublicKey(),
|
|
567
|
+
},
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
await this.users.get(userId)?.unsubscribe();
|
|
571
|
+
this.users.delete(userId);
|
|
572
|
+
|
|
573
|
+
return txSig;
|
|
574
|
+
}
|
|
575
|
+
|
|
533
576
|
public getUser(userId?: number): ClearingHouseUser {
|
|
534
577
|
userId = userId ?? this.activeUserId;
|
|
535
578
|
if (!this.users.has(userId)) {
|
|
@@ -589,57 +632,30 @@ export class ClearingHouse {
|
|
|
589
632
|
);
|
|
590
633
|
}
|
|
591
634
|
|
|
592
|
-
getRemainingAccounts(params: {
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
readablePerpMarketIndex?: number;
|
|
596
|
-
readableSpotMarketIndex?: number;
|
|
597
|
-
}): AccountMeta[] {
|
|
598
|
-
const userAccountAndSlot = this.getUserAccountAndSlot();
|
|
599
|
-
if (!userAccountAndSlot) {
|
|
600
|
-
throw Error(
|
|
601
|
-
'No user account found. Most likely user account does not exist or failed to fetch account'
|
|
602
|
-
);
|
|
603
|
-
}
|
|
604
|
-
const { data: userAccount, slot: lastUserPositionsSlot } =
|
|
605
|
-
userAccountAndSlot;
|
|
606
|
-
|
|
607
|
-
const oracleAccountMap = new Map<string, AccountMeta>();
|
|
608
|
-
const spotMarketAccountMap = new Map<number, AccountMeta>();
|
|
609
|
-
const perpMarketAccountMap = new Map<number, AccountMeta>();
|
|
610
|
-
for (const [marketIndexNum, slot] of this.marketLastSlotCache.entries()) {
|
|
611
|
-
// if cache has more recent slot than user positions account slot, add market to remaining accounts
|
|
612
|
-
// otherwise remove from slot
|
|
613
|
-
if (slot > lastUserPositionsSlot) {
|
|
614
|
-
const marketAccount = this.getPerpMarketAccount(marketIndexNum);
|
|
615
|
-
perpMarketAccountMap.set(marketIndexNum, {
|
|
616
|
-
pubkey: marketAccount.pubkey,
|
|
617
|
-
isSigner: false,
|
|
618
|
-
isWritable: false,
|
|
619
|
-
});
|
|
620
|
-
oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
|
|
621
|
-
pubkey: marketAccount.amm.oracle,
|
|
622
|
-
isSigner: false,
|
|
623
|
-
isWritable: false,
|
|
624
|
-
});
|
|
625
|
-
} else {
|
|
626
|
-
this.marketLastSlotCache.delete(marketIndexNum);
|
|
627
|
-
}
|
|
628
|
-
}
|
|
635
|
+
getRemainingAccounts(params: RemainingAccountParams): AccountMeta[] {
|
|
636
|
+
const { oracleAccountMap, spotMarketAccountMap, perpMarketAccountMap } =
|
|
637
|
+
this.getRemainingAccountMapsForUsers(params.userAccounts);
|
|
629
638
|
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
639
|
+
if (params.useMarketLastSlotCache) {
|
|
640
|
+
const lastUserPositionsSlot = this.getUserAccountAndSlot()?.slot;
|
|
641
|
+
for (const [marketIndex, slot] of this.marketLastSlotCache.entries()) {
|
|
642
|
+
// if cache has more recent slot than user positions account slot, add market to remaining accounts
|
|
643
|
+
// otherwise remove from slot
|
|
644
|
+
if (slot > lastUserPositionsSlot) {
|
|
645
|
+
const marketAccount = this.getPerpMarketAccount(marketIndex);
|
|
646
|
+
perpMarketAccountMap.set(marketIndex, {
|
|
647
|
+
pubkey: marketAccount.pubkey,
|
|
648
|
+
isSigner: false,
|
|
649
|
+
isWritable: false,
|
|
650
|
+
});
|
|
651
|
+
oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
|
|
652
|
+
pubkey: marketAccount.amm.oracle,
|
|
653
|
+
isSigner: false,
|
|
654
|
+
isWritable: false,
|
|
655
|
+
});
|
|
656
|
+
} else {
|
|
657
|
+
this.marketLastSlotCache.delete(marketIndex);
|
|
658
|
+
}
|
|
643
659
|
}
|
|
644
660
|
}
|
|
645
661
|
|
|
@@ -659,39 +675,21 @@ export class ClearingHouse {
|
|
|
659
675
|
});
|
|
660
676
|
}
|
|
661
677
|
|
|
662
|
-
if (params.
|
|
663
|
-
const
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
perpMarketAccountMap.set(params.writablePerpMarketIndex, {
|
|
667
|
-
pubkey: marketAccount.pubkey,
|
|
668
|
-
isSigner: false,
|
|
669
|
-
isWritable: true,
|
|
670
|
-
});
|
|
671
|
-
oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
|
|
672
|
-
pubkey: marketAccount.amm.oracle,
|
|
673
|
-
isSigner: false,
|
|
674
|
-
isWritable: false,
|
|
675
|
-
});
|
|
676
|
-
}
|
|
677
|
-
|
|
678
|
-
for (const spotPosition of userAccount.spotPositions) {
|
|
679
|
-
if (!isSpotPositionAvailable(spotPosition)) {
|
|
680
|
-
const spotMarketAccount = this.getSpotMarketAccount(
|
|
681
|
-
spotPosition.marketIndex
|
|
678
|
+
if (params.writablePerpMarketIndexes !== undefined) {
|
|
679
|
+
for (const writablePerpMarketIndex of params.writablePerpMarketIndexes) {
|
|
680
|
+
const marketAccount = this.getPerpMarketAccount(
|
|
681
|
+
writablePerpMarketIndex
|
|
682
682
|
);
|
|
683
|
-
|
|
684
|
-
pubkey:
|
|
683
|
+
perpMarketAccountMap.set(writablePerpMarketIndex, {
|
|
684
|
+
pubkey: marketAccount.pubkey,
|
|
685
|
+
isSigner: false,
|
|
686
|
+
isWritable: true,
|
|
687
|
+
});
|
|
688
|
+
oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
|
|
689
|
+
pubkey: marketAccount.amm.oracle,
|
|
685
690
|
isSigner: false,
|
|
686
691
|
isWritable: false,
|
|
687
692
|
});
|
|
688
|
-
if (spotMarketAccount.marketIndex !== 0) {
|
|
689
|
-
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
690
|
-
pubkey: spotMarketAccount.oracle,
|
|
691
|
-
isSigner: false,
|
|
692
|
-
isWritable: false,
|
|
693
|
-
});
|
|
694
|
-
}
|
|
695
693
|
}
|
|
696
694
|
}
|
|
697
695
|
|
|
@@ -713,21 +711,23 @@ export class ClearingHouse {
|
|
|
713
711
|
}
|
|
714
712
|
}
|
|
715
713
|
|
|
716
|
-
if (params.
|
|
717
|
-
const
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
isWritable: true,
|
|
724
|
-
});
|
|
725
|
-
if (spotMarketAccount.marketIndex !== 0) {
|
|
726
|
-
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
727
|
-
pubkey: spotMarketAccount.oracle,
|
|
714
|
+
if (params.writableSpotMarketIndexes !== undefined) {
|
|
715
|
+
for (const writableSpotMarketIndex of params.writableSpotMarketIndexes) {
|
|
716
|
+
const spotMarketAccount = this.getSpotMarketAccount(
|
|
717
|
+
writableSpotMarketIndex
|
|
718
|
+
);
|
|
719
|
+
spotMarketAccountMap.set(spotMarketAccount.marketIndex, {
|
|
720
|
+
pubkey: spotMarketAccount.pubkey,
|
|
728
721
|
isSigner: false,
|
|
729
|
-
isWritable:
|
|
722
|
+
isWritable: true,
|
|
730
723
|
});
|
|
724
|
+
if (!spotMarketAccount.oracle.equals(PublicKey.default)) {
|
|
725
|
+
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
726
|
+
pubkey: spotMarketAccount.oracle,
|
|
727
|
+
isSigner: false,
|
|
728
|
+
isWritable: false,
|
|
729
|
+
});
|
|
730
|
+
}
|
|
731
731
|
}
|
|
732
732
|
}
|
|
733
733
|
|
|
@@ -738,10 +738,63 @@ export class ClearingHouse {
|
|
|
738
738
|
];
|
|
739
739
|
}
|
|
740
740
|
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
741
|
+
getRemainingAccountMapsForUsers(userAccounts: UserAccount[]): {
|
|
742
|
+
oracleAccountMap: Map<string, AccountMeta>;
|
|
743
|
+
spotMarketAccountMap: Map<number, AccountMeta>;
|
|
744
|
+
perpMarketAccountMap: Map<number, AccountMeta>;
|
|
745
|
+
} {
|
|
746
|
+
const oracleAccountMap = new Map<string, AccountMeta>();
|
|
747
|
+
const spotMarketAccountMap = new Map<number, AccountMeta>();
|
|
748
|
+
const perpMarketAccountMap = new Map<number, AccountMeta>();
|
|
749
|
+
|
|
750
|
+
for (const userAccount of userAccounts) {
|
|
751
|
+
for (const spotPosition of userAccount.spotPositions) {
|
|
752
|
+
if (!isSpotPositionAvailable(spotPosition)) {
|
|
753
|
+
const spotMarket = this.getSpotMarketAccount(
|
|
754
|
+
spotPosition.marketIndex
|
|
755
|
+
);
|
|
756
|
+
spotMarketAccountMap.set(spotPosition.marketIndex, {
|
|
757
|
+
pubkey: spotMarket.pubkey,
|
|
758
|
+
isSigner: false,
|
|
759
|
+
isWritable: false,
|
|
760
|
+
});
|
|
761
|
+
|
|
762
|
+
if (!spotMarket.oracle.equals(PublicKey.default)) {
|
|
763
|
+
oracleAccountMap.set(spotMarket.oracle.toString(), {
|
|
764
|
+
pubkey: spotMarket.oracle,
|
|
765
|
+
isSigner: false,
|
|
766
|
+
isWritable: false,
|
|
767
|
+
});
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
for (const position of userAccount.perpPositions) {
|
|
772
|
+
if (!positionIsAvailable(position)) {
|
|
773
|
+
const market = this.getPerpMarketAccount(position.marketIndex);
|
|
774
|
+
perpMarketAccountMap.set(position.marketIndex, {
|
|
775
|
+
pubkey: market.pubkey,
|
|
776
|
+
isWritable: false,
|
|
777
|
+
isSigner: false,
|
|
778
|
+
});
|
|
779
|
+
oracleAccountMap.set(market.amm.oracle.toString(), {
|
|
780
|
+
pubkey: market.amm.oracle,
|
|
781
|
+
isWritable: false,
|
|
782
|
+
isSigner: false,
|
|
783
|
+
});
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
return {
|
|
789
|
+
oracleAccountMap,
|
|
790
|
+
spotMarketAccountMap,
|
|
791
|
+
perpMarketAccountMap,
|
|
792
|
+
};
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
public getOrder(orderId: number): Order | undefined {
|
|
796
|
+
return this.getUserAccount()?.orders.find(
|
|
797
|
+
(order) => order.orderId === orderId
|
|
745
798
|
);
|
|
746
799
|
}
|
|
747
800
|
|
|
@@ -834,21 +887,14 @@ export class ClearingHouse {
|
|
|
834
887
|
let remainingAccounts = [];
|
|
835
888
|
if (userInitialized) {
|
|
836
889
|
remainingAccounts = this.getRemainingAccounts({
|
|
837
|
-
|
|
890
|
+
userAccounts: [this.getUserAccount()],
|
|
891
|
+
useMarketLastSlotCache: true,
|
|
892
|
+
writableSpotMarketIndexes: [marketIndex],
|
|
838
893
|
});
|
|
839
894
|
} else {
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
pubkey: spotMarketAccount.oracle,
|
|
844
|
-
isSigner: false,
|
|
845
|
-
isWritable: false,
|
|
846
|
-
});
|
|
847
|
-
}
|
|
848
|
-
remainingAccounts.push({
|
|
849
|
-
pubkey: spotMarketAccount.pubkey,
|
|
850
|
-
isSigner: false,
|
|
851
|
-
isWritable: true,
|
|
895
|
+
remainingAccounts = this.getRemainingAccounts({
|
|
896
|
+
userAccounts: [],
|
|
897
|
+
writableSpotMarketIndexes: [marketIndex],
|
|
852
898
|
});
|
|
853
899
|
}
|
|
854
900
|
|
|
@@ -1164,7 +1210,9 @@ export class ClearingHouse {
|
|
|
1164
1210
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
1165
1211
|
|
|
1166
1212
|
const remainingAccounts = this.getRemainingAccounts({
|
|
1167
|
-
|
|
1213
|
+
userAccounts: [this.getUserAccount()],
|
|
1214
|
+
useMarketLastSlotCache: true,
|
|
1215
|
+
writableSpotMarketIndexes: [marketIndex],
|
|
1168
1216
|
});
|
|
1169
1217
|
|
|
1170
1218
|
const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
|
|
@@ -1228,9 +1276,29 @@ export class ClearingHouse {
|
|
|
1228
1276
|
toUserId
|
|
1229
1277
|
);
|
|
1230
1278
|
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1279
|
+
let remainingAccounts;
|
|
1280
|
+
if (this.users.has(fromUserId)) {
|
|
1281
|
+
remainingAccounts = this.getRemainingAccounts({
|
|
1282
|
+
userAccounts: [this.users.get(fromUserId).getUserAccount()],
|
|
1283
|
+
useMarketLastSlotCache: true,
|
|
1284
|
+
writableSpotMarketIndexes: [marketIndex],
|
|
1285
|
+
});
|
|
1286
|
+
} else {
|
|
1287
|
+
const userAccountPublicKey = getUserAccountPublicKeySync(
|
|
1288
|
+
this.program.programId,
|
|
1289
|
+
this.authority,
|
|
1290
|
+
fromUserId
|
|
1291
|
+
);
|
|
1292
|
+
|
|
1293
|
+
const fromUserAccount = (await this.program.account.user.fetch(
|
|
1294
|
+
userAccountPublicKey
|
|
1295
|
+
)) as UserAccount;
|
|
1296
|
+
remainingAccounts = this.getRemainingAccounts({
|
|
1297
|
+
userAccounts: [fromUserAccount],
|
|
1298
|
+
useMarketLastSlotCache: true,
|
|
1299
|
+
writableSpotMarketIndexes: [marketIndex],
|
|
1300
|
+
});
|
|
1301
|
+
}
|
|
1234
1302
|
|
|
1235
1303
|
return await this.program.instruction.transferDeposit(marketIndex, amount, {
|
|
1236
1304
|
accounts: {
|
|
@@ -1261,6 +1329,7 @@ export class ClearingHouse {
|
|
|
1261
1329
|
const spotMarket = this.getSpotMarketAccount(marketIndex);
|
|
1262
1330
|
return await this.program.instruction.updateSpotMarketCumulativeInterest({
|
|
1263
1331
|
accounts: {
|
|
1332
|
+
state: await this.getStatePublicKey(),
|
|
1264
1333
|
spotMarket: spotMarket.pubkey,
|
|
1265
1334
|
},
|
|
1266
1335
|
});
|
|
@@ -1285,33 +1354,11 @@ export class ClearingHouse {
|
|
|
1285
1354
|
const settleeUserAccount = (await this.program.account.user.fetch(
|
|
1286
1355
|
settleeUserAccountPublicKey
|
|
1287
1356
|
)) as UserAccount;
|
|
1288
|
-
const userPositions = settleeUserAccount.perpPositions;
|
|
1289
|
-
const remainingAccounts = [];
|
|
1290
|
-
|
|
1291
|
-
let foundMarket = false;
|
|
1292
|
-
for (const position of userPositions) {
|
|
1293
|
-
if (!positionIsAvailable(position)) {
|
|
1294
|
-
const marketPublicKey = await getMarketPublicKey(
|
|
1295
|
-
this.program.programId,
|
|
1296
|
-
position.marketIndex
|
|
1297
|
-
);
|
|
1298
|
-
remainingAccounts.push({
|
|
1299
|
-
pubkey: marketPublicKey,
|
|
1300
|
-
isWritable: true,
|
|
1301
|
-
isSigner: false,
|
|
1302
|
-
});
|
|
1303
|
-
|
|
1304
|
-
if (marketIndex === position.marketIndex) {
|
|
1305
|
-
foundMarket = true;
|
|
1306
|
-
}
|
|
1307
|
-
}
|
|
1308
|
-
}
|
|
1309
1357
|
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
}
|
|
1358
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
1359
|
+
userAccounts: [settleeUserAccount],
|
|
1360
|
+
writablePerpMarketIndexes: [marketIndex],
|
|
1361
|
+
});
|
|
1315
1362
|
|
|
1316
1363
|
return this.program.instruction.settleLp(marketIndex, {
|
|
1317
1364
|
accounts: {
|
|
@@ -1341,7 +1388,9 @@ export class ClearingHouse {
|
|
|
1341
1388
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
1342
1389
|
|
|
1343
1390
|
const remainingAccounts = this.getRemainingAccounts({
|
|
1344
|
-
|
|
1391
|
+
userAccounts: [this.getUserAccount()],
|
|
1392
|
+
useMarketLastSlotCache: true,
|
|
1393
|
+
writablePerpMarketIndexes: [marketIndex],
|
|
1345
1394
|
});
|
|
1346
1395
|
|
|
1347
1396
|
if (sharesToBurn == undefined) {
|
|
@@ -1382,7 +1431,9 @@ export class ClearingHouse {
|
|
|
1382
1431
|
): Promise<TransactionInstruction> {
|
|
1383
1432
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
1384
1433
|
const remainingAccounts = this.getRemainingAccounts({
|
|
1385
|
-
|
|
1434
|
+
userAccounts: [this.getUserAccount()],
|
|
1435
|
+
useMarketLastSlotCache: true,
|
|
1436
|
+
writablePerpMarketIndexes: [marketIndex],
|
|
1386
1437
|
});
|
|
1387
1438
|
|
|
1388
1439
|
return this.program.instruction.addLiquidity(amount, marketIndex, {
|
|
@@ -1492,6 +1543,8 @@ export class ClearingHouse {
|
|
|
1492
1543
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
1493
1544
|
|
|
1494
1545
|
const remainingAccounts = this.getRemainingAccounts({
|
|
1546
|
+
userAccounts: [this.getUserAccount()],
|
|
1547
|
+
useMarketLastSlotCache: true,
|
|
1495
1548
|
readablePerpMarketIndex: orderParams.marketIndex,
|
|
1496
1549
|
});
|
|
1497
1550
|
|
|
@@ -1599,7 +1652,7 @@ export class ClearingHouse {
|
|
|
1599
1652
|
});
|
|
1600
1653
|
}
|
|
1601
1654
|
|
|
1602
|
-
public async cancelOrder(orderId?:
|
|
1655
|
+
public async cancelOrder(orderId?: number): Promise<TransactionSignature> {
|
|
1603
1656
|
const { txSig } = await this.txSender.send(
|
|
1604
1657
|
wrapInTx(await this.getCancelOrderIx(orderId)),
|
|
1605
1658
|
[],
|
|
@@ -1608,10 +1661,15 @@ export class ClearingHouse {
|
|
|
1608
1661
|
return txSig;
|
|
1609
1662
|
}
|
|
1610
1663
|
|
|
1611
|
-
public async getCancelOrderIx(
|
|
1664
|
+
public async getCancelOrderIx(
|
|
1665
|
+
orderId?: number
|
|
1666
|
+
): Promise<TransactionInstruction> {
|
|
1612
1667
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
1613
1668
|
|
|
1614
|
-
const remainingAccounts = this.getRemainingAccounts({
|
|
1669
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
1670
|
+
userAccounts: [this.getUserAccount()],
|
|
1671
|
+
useMarketLastSlotCache: true,
|
|
1672
|
+
});
|
|
1615
1673
|
|
|
1616
1674
|
return await this.program.instruction.cancelOrder(orderId ?? null, {
|
|
1617
1675
|
accounts: {
|
|
@@ -1642,7 +1700,10 @@ export class ClearingHouse {
|
|
|
1642
1700
|
const order = this.getOrderByUserId(userOrderId);
|
|
1643
1701
|
const oracle = this.getPerpMarketAccount(order.marketIndex).amm.oracle;
|
|
1644
1702
|
|
|
1645
|
-
const remainingAccounts = this.getRemainingAccounts({
|
|
1703
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
1704
|
+
userAccounts: [this.getUserAccount()],
|
|
1705
|
+
useMarketLastSlotCache: true,
|
|
1706
|
+
});
|
|
1646
1707
|
|
|
1647
1708
|
return await this.program.instruction.cancelOrderByUserId(userOrderId, {
|
|
1648
1709
|
accounts: {
|
|
@@ -1658,7 +1719,7 @@ export class ClearingHouse {
|
|
|
1658
1719
|
public async fillOrder(
|
|
1659
1720
|
userAccountPublicKey: PublicKey,
|
|
1660
1721
|
user: UserAccount,
|
|
1661
|
-
order?: Order,
|
|
1722
|
+
order?: Pick<Order, 'marketIndex' | 'orderId'>,
|
|
1662
1723
|
makerInfo?: MakerInfo,
|
|
1663
1724
|
referrerInfo?: ReferrerInfo
|
|
1664
1725
|
): Promise<TransactionSignature> {
|
|
@@ -1695,72 +1756,19 @@ export class ClearingHouse {
|
|
|
1695
1756
|
|
|
1696
1757
|
const marketIndex = order
|
|
1697
1758
|
? order.marketIndex
|
|
1698
|
-
: userAccount.orders.find(
|
|
1699
|
-
order.orderId
|
|
1759
|
+
: userAccount.orders.find(
|
|
1760
|
+
(order) => order.orderId === userAccount.nextOrderId - 1
|
|
1700
1761
|
).marketIndex;
|
|
1701
|
-
const marketAccount = this.getPerpMarketAccount(marketIndex);
|
|
1702
|
-
|
|
1703
|
-
const oracleAccountMap = new Map<string, AccountMeta>();
|
|
1704
|
-
const spotMarketAccountMap = new Map<number, AccountMeta>();
|
|
1705
|
-
const perpMarketAccountMap = new Map<number, AccountMeta>();
|
|
1706
|
-
|
|
1707
|
-
for (const spotPosition of userAccount.spotPositions) {
|
|
1708
|
-
if (!isSpotPositionAvailable(spotPosition)) {
|
|
1709
|
-
const spotMarketAccount = this.getSpotMarketAccount(
|
|
1710
|
-
spotPosition.marketIndex
|
|
1711
|
-
);
|
|
1712
|
-
spotMarketAccountMap.set(spotPosition.marketIndex, {
|
|
1713
|
-
pubkey: spotMarketAccount.pubkey,
|
|
1714
|
-
isSigner: false,
|
|
1715
|
-
isWritable: false,
|
|
1716
|
-
});
|
|
1717
|
-
|
|
1718
|
-
if (!spotMarketAccount.oracle.equals(PublicKey.default)) {
|
|
1719
|
-
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
1720
|
-
pubkey: spotMarketAccount.oracle,
|
|
1721
|
-
isSigner: false,
|
|
1722
|
-
isWritable: false,
|
|
1723
|
-
});
|
|
1724
|
-
}
|
|
1725
|
-
}
|
|
1726
|
-
}
|
|
1727
1762
|
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
position.marketIndex !== order.marketIndex
|
|
1732
|
-
) {
|
|
1733
|
-
const market = this.getPerpMarketAccount(position.marketIndex);
|
|
1734
|
-
perpMarketAccountMap.set(position.marketIndex, {
|
|
1735
|
-
pubkey: market.pubkey,
|
|
1736
|
-
isWritable: false,
|
|
1737
|
-
isSigner: false,
|
|
1738
|
-
});
|
|
1739
|
-
oracleAccountMap.set(market.amm.oracle.toString(), {
|
|
1740
|
-
pubkey: market.amm.oracle,
|
|
1741
|
-
isWritable: false,
|
|
1742
|
-
isSigner: false,
|
|
1743
|
-
});
|
|
1744
|
-
}
|
|
1763
|
+
const userAccounts = [userAccount];
|
|
1764
|
+
if (makerInfo !== undefined) {
|
|
1765
|
+
userAccounts.push(makerInfo.makerUserAccount);
|
|
1745
1766
|
}
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
isWritable: true,
|
|
1750
|
-
isSigner: false,
|
|
1751
|
-
});
|
|
1752
|
-
oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
|
|
1753
|
-
pubkey: marketAccount.amm.oracle,
|
|
1754
|
-
isWritable: false,
|
|
1755
|
-
isSigner: false,
|
|
1767
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
1768
|
+
userAccounts,
|
|
1769
|
+
writablePerpMarketIndexes: [marketIndex],
|
|
1756
1770
|
});
|
|
1757
1771
|
|
|
1758
|
-
const remainingAccounts = [
|
|
1759
|
-
...oracleAccountMap.values(),
|
|
1760
|
-
...spotMarketAccountMap.values(),
|
|
1761
|
-
...perpMarketAccountMap.values(),
|
|
1762
|
-
];
|
|
1763
|
-
|
|
1764
1772
|
if (makerInfo) {
|
|
1765
1773
|
remainingAccounts.push({
|
|
1766
1774
|
pubkey: makerInfo.maker,
|
|
@@ -1821,6 +1829,8 @@ export class ClearingHouse {
|
|
|
1821
1829
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
1822
1830
|
|
|
1823
1831
|
const remainingAccounts = this.getRemainingAccounts({
|
|
1832
|
+
userAccounts: [this.getUserAccount()],
|
|
1833
|
+
useMarketLastSlotCache: true,
|
|
1824
1834
|
readableSpotMarketIndex: orderParams.marketIndex,
|
|
1825
1835
|
});
|
|
1826
1836
|
|
|
@@ -1878,86 +1888,30 @@ export class ClearingHouse {
|
|
|
1878
1888
|
|
|
1879
1889
|
const marketIndex = order
|
|
1880
1890
|
? order.marketIndex
|
|
1881
|
-
: userAccount.orders.find(
|
|
1882
|
-
order.orderId
|
|
1891
|
+
: userAccount.orders.find(
|
|
1892
|
+
(order) => order.orderId === userAccount.nextOrderId - 1
|
|
1883
1893
|
).marketIndex;
|
|
1884
1894
|
|
|
1885
|
-
const
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
pubkey: spotMarket.pubkey,
|
|
1894
|
-
isSigner: false,
|
|
1895
|
-
isWritable: false,
|
|
1896
|
-
});
|
|
1895
|
+
const userAccounts = [userAccount];
|
|
1896
|
+
if (makerInfo !== undefined) {
|
|
1897
|
+
userAccounts.push(makerInfo.makerUserAccount);
|
|
1898
|
+
}
|
|
1899
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
1900
|
+
userAccounts,
|
|
1901
|
+
writableSpotMarketIndexes: [marketIndex, QUOTE_SPOT_MARKET_INDEX],
|
|
1902
|
+
});
|
|
1897
1903
|
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
if (!positionIsAvailable(position)) {
|
|
1910
|
-
const market = this.getPerpMarketAccount(position.marketIndex);
|
|
1911
|
-
perpMarketAccountMap.set(position.marketIndex, {
|
|
1912
|
-
pubkey: market.pubkey,
|
|
1913
|
-
isWritable: false,
|
|
1914
|
-
isSigner: false,
|
|
1915
|
-
});
|
|
1916
|
-
oracleAccountMap.set(market.amm.oracle.toString(), {
|
|
1917
|
-
pubkey: market.amm.oracle,
|
|
1918
|
-
isWritable: false,
|
|
1919
|
-
isSigner: false,
|
|
1920
|
-
});
|
|
1921
|
-
}
|
|
1922
|
-
}
|
|
1923
|
-
|
|
1924
|
-
const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
|
|
1925
|
-
spotMarketAccountMap.set(marketIndex, {
|
|
1926
|
-
pubkey: spotMarketAccount.pubkey,
|
|
1927
|
-
isWritable: true,
|
|
1928
|
-
isSigner: false,
|
|
1929
|
-
});
|
|
1930
|
-
if (!spotMarketAccount.oracle.equals(PublicKey.default)) {
|
|
1931
|
-
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
1932
|
-
pubkey: spotMarketAccount.oracle,
|
|
1933
|
-
isWritable: false,
|
|
1934
|
-
isSigner: false,
|
|
1935
|
-
});
|
|
1936
|
-
}
|
|
1937
|
-
const quoteMarketAccount = this.getQuoteSpotMarketAccount();
|
|
1938
|
-
spotMarketAccountMap.set(quoteMarketAccount.marketIndex, {
|
|
1939
|
-
pubkey: quoteMarketAccount.pubkey,
|
|
1940
|
-
isWritable: true,
|
|
1941
|
-
isSigner: false,
|
|
1942
|
-
});
|
|
1943
|
-
|
|
1944
|
-
const remainingAccounts = [
|
|
1945
|
-
...oracleAccountMap.values(),
|
|
1946
|
-
...spotMarketAccountMap.values(),
|
|
1947
|
-
...perpMarketAccountMap.values(),
|
|
1948
|
-
];
|
|
1949
|
-
|
|
1950
|
-
if (makerInfo) {
|
|
1951
|
-
remainingAccounts.push({
|
|
1952
|
-
pubkey: makerInfo.maker,
|
|
1953
|
-
isWritable: true,
|
|
1954
|
-
isSigner: false,
|
|
1955
|
-
});
|
|
1956
|
-
remainingAccounts.push({
|
|
1957
|
-
pubkey: makerInfo.makerStats,
|
|
1958
|
-
isWritable: true,
|
|
1959
|
-
isSigner: false,
|
|
1960
|
-
});
|
|
1904
|
+
if (makerInfo) {
|
|
1905
|
+
remainingAccounts.push({
|
|
1906
|
+
pubkey: makerInfo.maker,
|
|
1907
|
+
isWritable: true,
|
|
1908
|
+
isSigner: false,
|
|
1909
|
+
});
|
|
1910
|
+
remainingAccounts.push({
|
|
1911
|
+
pubkey: makerInfo.makerStats,
|
|
1912
|
+
isWritable: true,
|
|
1913
|
+
isSigner: false,
|
|
1914
|
+
});
|
|
1961
1915
|
}
|
|
1962
1916
|
|
|
1963
1917
|
if (referrerInfo) {
|
|
@@ -2047,12 +2001,12 @@ export class ClearingHouse {
|
|
|
2047
2001
|
isSigner: false,
|
|
2048
2002
|
});
|
|
2049
2003
|
remainingAccounts.push({
|
|
2050
|
-
pubkey:
|
|
2004
|
+
pubkey: this.getSpotMarketAccount(marketIndex).vault,
|
|
2051
2005
|
isWritable: true,
|
|
2052
2006
|
isSigner: false,
|
|
2053
2007
|
});
|
|
2054
2008
|
remainingAccounts.push({
|
|
2055
|
-
pubkey:
|
|
2009
|
+
pubkey: this.getQuoteSpotMarketAccount().vault,
|
|
2056
2010
|
isWritable: true,
|
|
2057
2011
|
isSigner: false,
|
|
2058
2012
|
});
|
|
@@ -2101,176 +2055,25 @@ export class ClearingHouse {
|
|
|
2101
2055
|
): Promise<TransactionInstruction> {
|
|
2102
2056
|
const fillerPublicKey = await this.getUserAccountPublicKey();
|
|
2103
2057
|
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
);
|
|
2116
|
-
spotMarketAccountMap.set(spotPosition.marketIndex, {
|
|
2117
|
-
pubkey: spotMarketAccount.pubkey,
|
|
2118
|
-
isSigner: false,
|
|
2119
|
-
isWritable: false,
|
|
2120
|
-
});
|
|
2121
|
-
|
|
2122
|
-
if (!spotMarketAccount.oracle.equals(PublicKey.default)) {
|
|
2123
|
-
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
2124
|
-
pubkey: spotMarketAccount.oracle,
|
|
2125
|
-
isSigner: false,
|
|
2126
|
-
isWritable: false,
|
|
2127
|
-
});
|
|
2128
|
-
}
|
|
2129
|
-
}
|
|
2130
|
-
}
|
|
2131
|
-
|
|
2132
|
-
for (const position of userAccount.perpPositions) {
|
|
2133
|
-
if (
|
|
2134
|
-
!positionIsAvailable(position) &&
|
|
2135
|
-
position.marketIndex !== order.marketIndex
|
|
2136
|
-
) {
|
|
2137
|
-
const market = this.getPerpMarketAccount(position.marketIndex);
|
|
2138
|
-
perpMarketAccountMap.set(position.marketIndex, {
|
|
2139
|
-
pubkey: market.pubkey,
|
|
2140
|
-
isWritable: false,
|
|
2141
|
-
isSigner: false,
|
|
2142
|
-
});
|
|
2143
|
-
oracleAccountMap.set(market.amm.oracle.toString(), {
|
|
2144
|
-
pubkey: market.amm.oracle,
|
|
2145
|
-
isWritable: false,
|
|
2146
|
-
isSigner: false,
|
|
2147
|
-
});
|
|
2148
|
-
}
|
|
2058
|
+
let remainingAccountsParams;
|
|
2059
|
+
if (isVariant(order.marketType, 'perp')) {
|
|
2060
|
+
remainingAccountsParams = {
|
|
2061
|
+
userAccounts: [userAccount],
|
|
2062
|
+
writablePerpMarketIndexes: [order.marketIndex],
|
|
2063
|
+
};
|
|
2064
|
+
} else {
|
|
2065
|
+
remainingAccountsParams = {
|
|
2066
|
+
userAccounts: [userAccount],
|
|
2067
|
+
writableSpotMarketIndexes: [order.marketIndex, QUOTE_SPOT_MARKET_INDEX],
|
|
2068
|
+
};
|
|
2149
2069
|
}
|
|
2150
2070
|
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
isWritable: true,
|
|
2154
|
-
isSigner: false,
|
|
2155
|
-
});
|
|
2156
|
-
oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
|
|
2157
|
-
pubkey: marketAccount.amm.oracle,
|
|
2158
|
-
isWritable: false,
|
|
2159
|
-
isSigner: false,
|
|
2160
|
-
});
|
|
2161
|
-
|
|
2162
|
-
const remainingAccounts = [
|
|
2163
|
-
...oracleAccountMap.values(),
|
|
2164
|
-
...spotMarketAccountMap.values(),
|
|
2165
|
-
...perpMarketAccountMap.values(),
|
|
2166
|
-
];
|
|
2167
|
-
|
|
2168
|
-
const orderId = order.orderId;
|
|
2169
|
-
return await this.program.instruction.triggerOrder(orderId, {
|
|
2170
|
-
accounts: {
|
|
2171
|
-
state: await this.getStatePublicKey(),
|
|
2172
|
-
filler: fillerPublicKey,
|
|
2173
|
-
user: userAccountPublicKey,
|
|
2174
|
-
authority: this.wallet.publicKey,
|
|
2175
|
-
},
|
|
2176
|
-
remainingAccounts,
|
|
2177
|
-
});
|
|
2178
|
-
}
|
|
2179
|
-
|
|
2180
|
-
public async triggerSpotOrder(
|
|
2181
|
-
userAccountPublicKey: PublicKey,
|
|
2182
|
-
user: UserAccount,
|
|
2183
|
-
order: Order
|
|
2184
|
-
): Promise<TransactionSignature> {
|
|
2185
|
-
const { txSig } = await this.txSender.send(
|
|
2186
|
-
wrapInTx(
|
|
2187
|
-
await this.getTriggerSpotOrderIx(userAccountPublicKey, user, order)
|
|
2188
|
-
),
|
|
2189
|
-
[],
|
|
2190
|
-
this.opts
|
|
2071
|
+
const remainingAccounts = this.getRemainingAccounts(
|
|
2072
|
+
remainingAccountsParams
|
|
2191
2073
|
);
|
|
2192
|
-
return txSig;
|
|
2193
|
-
}
|
|
2194
|
-
|
|
2195
|
-
public async getTriggerSpotOrderIx(
|
|
2196
|
-
userAccountPublicKey: PublicKey,
|
|
2197
|
-
userAccount: UserAccount,
|
|
2198
|
-
order: Order
|
|
2199
|
-
): Promise<TransactionInstruction> {
|
|
2200
|
-
const fillerPublicKey = await this.getUserAccountPublicKey();
|
|
2201
|
-
|
|
2202
|
-
const marketIndex = order.marketIndex;
|
|
2203
|
-
const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
|
|
2204
|
-
|
|
2205
|
-
const oracleAccountMap = new Map<string, AccountMeta>();
|
|
2206
|
-
const spotMarketAccountMap = new Map<number, AccountMeta>();
|
|
2207
|
-
const perpMarketAccountMap = new Map<number, AccountMeta>();
|
|
2208
|
-
|
|
2209
|
-
for (const spotPosition of userAccount.spotPositions) {
|
|
2210
|
-
if (!isSpotPositionAvailable(spotPosition)) {
|
|
2211
|
-
const spotMarketAccount = this.getSpotMarketAccount(
|
|
2212
|
-
spotPosition.marketIndex
|
|
2213
|
-
);
|
|
2214
|
-
spotMarketAccountMap.set(spotPosition.marketIndex, {
|
|
2215
|
-
pubkey: spotMarketAccount.pubkey,
|
|
2216
|
-
isSigner: false,
|
|
2217
|
-
isWritable: false,
|
|
2218
|
-
});
|
|
2219
|
-
|
|
2220
|
-
if (!spotMarketAccount.oracle.equals(PublicKey.default)) {
|
|
2221
|
-
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
2222
|
-
pubkey: spotMarketAccount.oracle,
|
|
2223
|
-
isSigner: false,
|
|
2224
|
-
isWritable: false,
|
|
2225
|
-
});
|
|
2226
|
-
}
|
|
2227
|
-
}
|
|
2228
|
-
}
|
|
2229
|
-
|
|
2230
|
-
for (const position of userAccount.perpPositions) {
|
|
2231
|
-
if (
|
|
2232
|
-
!positionIsAvailable(position) &&
|
|
2233
|
-
position.marketIndex !== order.marketIndex
|
|
2234
|
-
) {
|
|
2235
|
-
const market = this.getPerpMarketAccount(position.marketIndex);
|
|
2236
|
-
perpMarketAccountMap.set(position.marketIndex, {
|
|
2237
|
-
pubkey: market.pubkey,
|
|
2238
|
-
isWritable: false,
|
|
2239
|
-
isSigner: false,
|
|
2240
|
-
});
|
|
2241
|
-
oracleAccountMap.set(market.amm.oracle.toString(), {
|
|
2242
|
-
pubkey: market.amm.oracle,
|
|
2243
|
-
isWritable: false,
|
|
2244
|
-
isSigner: false,
|
|
2245
|
-
});
|
|
2246
|
-
}
|
|
2247
|
-
}
|
|
2248
|
-
|
|
2249
|
-
const quoteSpotMarket = this.getQuoteSpotMarketAccount();
|
|
2250
|
-
spotMarketAccountMap.set(quoteSpotMarket.marketIndex, {
|
|
2251
|
-
pubkey: quoteSpotMarket.pubkey,
|
|
2252
|
-
isWritable: true,
|
|
2253
|
-
isSigner: false,
|
|
2254
|
-
});
|
|
2255
|
-
spotMarketAccountMap.set(marketIndex, {
|
|
2256
|
-
pubkey: spotMarketAccount.pubkey,
|
|
2257
|
-
isWritable: false,
|
|
2258
|
-
isSigner: false,
|
|
2259
|
-
});
|
|
2260
|
-
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
2261
|
-
pubkey: spotMarketAccount.oracle,
|
|
2262
|
-
isWritable: false,
|
|
2263
|
-
isSigner: false,
|
|
2264
|
-
});
|
|
2265
|
-
|
|
2266
|
-
const remainingAccounts = [
|
|
2267
|
-
...oracleAccountMap.values(),
|
|
2268
|
-
...spotMarketAccountMap.values(),
|
|
2269
|
-
...perpMarketAccountMap.values(),
|
|
2270
|
-
];
|
|
2271
2074
|
|
|
2272
2075
|
const orderId = order.orderId;
|
|
2273
|
-
return await this.program.instruction.
|
|
2076
|
+
return await this.program.instruction.triggerOrder(orderId, {
|
|
2274
2077
|
accounts: {
|
|
2275
2078
|
state: await this.getStatePublicKey(),
|
|
2276
2079
|
filler: fillerPublicKey,
|
|
@@ -2306,9 +2109,14 @@ export class ClearingHouse {
|
|
|
2306
2109
|
const userStatsPublicKey = await this.getUserStatsAccountPublicKey();
|
|
2307
2110
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
2308
2111
|
|
|
2112
|
+
const userAccounts = [this.getUserAccount()];
|
|
2113
|
+
if (makerInfo !== undefined) {
|
|
2114
|
+
userAccounts.push(makerInfo.makerUserAccount);
|
|
2115
|
+
}
|
|
2309
2116
|
const remainingAccounts = this.getRemainingAccounts({
|
|
2310
|
-
|
|
2311
|
-
|
|
2117
|
+
userAccounts,
|
|
2118
|
+
useMarketLastSlotCache: true,
|
|
2119
|
+
writablePerpMarketIndexes: [orderParams.marketIndex],
|
|
2312
2120
|
});
|
|
2313
2121
|
|
|
2314
2122
|
let makerOrderId = null;
|
|
@@ -2381,10 +2189,10 @@ export class ClearingHouse {
|
|
|
2381
2189
|
const userStatsPublicKey = this.getUserStatsAccountPublicKey();
|
|
2382
2190
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
2383
2191
|
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2192
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
2193
|
+
userAccounts: [this.getUserAccount(), takerInfo.takerUserAccount],
|
|
2194
|
+
useMarketLastSlotCache: true,
|
|
2195
|
+
writablePerpMarketIndexes: [orderParams.marketIndex],
|
|
2388
2196
|
});
|
|
2389
2197
|
|
|
2390
2198
|
if (referrerInfo) {
|
|
@@ -2400,7 +2208,7 @@ export class ClearingHouse {
|
|
|
2400
2208
|
});
|
|
2401
2209
|
}
|
|
2402
2210
|
|
|
2403
|
-
const takerOrderId = takerInfo
|
|
2211
|
+
const takerOrderId = takerInfo.order.orderId;
|
|
2404
2212
|
return await this.program.instruction.placeAndMake(
|
|
2405
2213
|
orderParams,
|
|
2406
2214
|
takerOrderId,
|
|
@@ -2497,70 +2305,12 @@ export class ClearingHouse {
|
|
|
2497
2305
|
settleeUserAccount: UserAccount,
|
|
2498
2306
|
marketIndex: number
|
|
2499
2307
|
): Promise<TransactionInstruction> {
|
|
2500
|
-
const
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
for (const position of settleeUserAccount.perpPositions) {
|
|
2505
|
-
if (!positionIsAvailable(position)) {
|
|
2506
|
-
const market = this.getPerpMarketAccount(position.marketIndex);
|
|
2507
|
-
perpMarketAccountMap.set(position.marketIndex, {
|
|
2508
|
-
pubkey: market.pubkey,
|
|
2509
|
-
isWritable: false,
|
|
2510
|
-
isSigner: false,
|
|
2511
|
-
});
|
|
2512
|
-
oracleAccountMap.set(market.amm.oracle.toString(), {
|
|
2513
|
-
pubkey: market.amm.oracle,
|
|
2514
|
-
isWritable: false,
|
|
2515
|
-
isSigner: false,
|
|
2516
|
-
});
|
|
2517
|
-
}
|
|
2518
|
-
}
|
|
2519
|
-
|
|
2520
|
-
for (const spotPosition of settleeUserAccount.spotPositions) {
|
|
2521
|
-
if (!isSpotPositionAvailable(spotPosition)) {
|
|
2522
|
-
const spotMarketAccount = this.getSpotMarketAccount(
|
|
2523
|
-
spotPosition.marketIndex
|
|
2524
|
-
);
|
|
2525
|
-
spotMarketAccountMap.set(spotPosition.marketIndex, {
|
|
2526
|
-
pubkey: spotMarketAccount.pubkey,
|
|
2527
|
-
isSigner: false,
|
|
2528
|
-
isWritable: false,
|
|
2529
|
-
});
|
|
2530
|
-
if (spotMarketAccount.marketIndex !== 0) {
|
|
2531
|
-
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
2532
|
-
pubkey: spotMarketAccount.oracle,
|
|
2533
|
-
isSigner: false,
|
|
2534
|
-
isWritable: false,
|
|
2535
|
-
});
|
|
2536
|
-
}
|
|
2537
|
-
}
|
|
2538
|
-
}
|
|
2539
|
-
|
|
2540
|
-
const marketAccount = this.getPerpMarketAccount(marketIndex);
|
|
2541
|
-
perpMarketAccountMap.set(marketIndex, {
|
|
2542
|
-
pubkey: marketAccount.pubkey,
|
|
2543
|
-
isSigner: false,
|
|
2544
|
-
isWritable: true,
|
|
2545
|
-
});
|
|
2546
|
-
oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
|
|
2547
|
-
pubkey: marketAccount.amm.oracle,
|
|
2548
|
-
isSigner: false,
|
|
2549
|
-
isWritable: false,
|
|
2550
|
-
});
|
|
2551
|
-
|
|
2552
|
-
spotMarketAccountMap.set(QUOTE_SPOT_MARKET_INDEX, {
|
|
2553
|
-
pubkey: this.getSpotMarketAccount(QUOTE_SPOT_MARKET_INDEX).pubkey,
|
|
2554
|
-
isSigner: false,
|
|
2555
|
-
isWritable: true,
|
|
2308
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
2309
|
+
userAccounts: [settleeUserAccount],
|
|
2310
|
+
writablePerpMarketIndexes: [marketIndex],
|
|
2311
|
+
writableSpotMarketIndexes: [QUOTE_SPOT_MARKET_INDEX],
|
|
2556
2312
|
});
|
|
2557
2313
|
|
|
2558
|
-
const remainingAccounts = [
|
|
2559
|
-
...oracleAccountMap.values(),
|
|
2560
|
-
...spotMarketAccountMap.values(),
|
|
2561
|
-
...perpMarketAccountMap.values(),
|
|
2562
|
-
];
|
|
2563
|
-
|
|
2564
2314
|
return await this.program.instruction.settlePnl(marketIndex, {
|
|
2565
2315
|
accounts: {
|
|
2566
2316
|
state: await this.getStatePublicKey(),
|
|
@@ -2595,69 +2345,12 @@ export class ClearingHouse {
|
|
|
2595
2345
|
settleeUserAccount: UserAccount,
|
|
2596
2346
|
marketIndex: number
|
|
2597
2347
|
): Promise<TransactionInstruction> {
|
|
2598
|
-
const
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
if (!positionIsAvailable(position)) {
|
|
2603
|
-
const market = this.getPerpMarketAccount(position.marketIndex);
|
|
2604
|
-
marketAccountMap.set(position.marketIndex, {
|
|
2605
|
-
pubkey: market.pubkey,
|
|
2606
|
-
isWritable: false,
|
|
2607
|
-
isSigner: false,
|
|
2608
|
-
});
|
|
2609
|
-
oracleAccountMap.set(market.amm.oracle.toString(), {
|
|
2610
|
-
pubkey: market.amm.oracle,
|
|
2611
|
-
isWritable: false,
|
|
2612
|
-
isSigner: false,
|
|
2613
|
-
});
|
|
2614
|
-
}
|
|
2615
|
-
}
|
|
2616
|
-
|
|
2617
|
-
for (const userBankBalance of settleeUserAccount.spotPositions) {
|
|
2618
|
-
if (!userBankBalance.balance.eq(ZERO)) {
|
|
2619
|
-
const bankAccount = this.getSpotMarketAccount(
|
|
2620
|
-
userBankBalance.marketIndex
|
|
2621
|
-
);
|
|
2622
|
-
spotMarketAccountMap.set(userBankBalance.marketIndex, {
|
|
2623
|
-
pubkey: bankAccount.pubkey,
|
|
2624
|
-
isSigner: false,
|
|
2625
|
-
isWritable: false,
|
|
2626
|
-
});
|
|
2627
|
-
if (bankAccount.marketIndex !== 0) {
|
|
2628
|
-
oracleAccountMap.set(bankAccount.oracle.toString(), {
|
|
2629
|
-
pubkey: bankAccount.oracle,
|
|
2630
|
-
isSigner: false,
|
|
2631
|
-
isWritable: false,
|
|
2632
|
-
});
|
|
2633
|
-
}
|
|
2634
|
-
}
|
|
2635
|
-
}
|
|
2636
|
-
|
|
2637
|
-
const marketAccount = this.getPerpMarketAccount(marketIndex);
|
|
2638
|
-
marketAccountMap.set(marketIndex, {
|
|
2639
|
-
pubkey: marketAccount.pubkey,
|
|
2640
|
-
isSigner: false,
|
|
2641
|
-
isWritable: true,
|
|
2642
|
-
});
|
|
2643
|
-
oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
|
|
2644
|
-
pubkey: marketAccount.amm.oracle,
|
|
2645
|
-
isSigner: false,
|
|
2646
|
-
isWritable: false,
|
|
2647
|
-
});
|
|
2648
|
-
|
|
2649
|
-
spotMarketAccountMap.set(QUOTE_SPOT_MARKET_INDEX, {
|
|
2650
|
-
pubkey: this.getSpotMarketAccount(QUOTE_SPOT_MARKET_INDEX).pubkey,
|
|
2651
|
-
isSigner: false,
|
|
2652
|
-
isWritable: true,
|
|
2348
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
2349
|
+
userAccounts: [settleeUserAccount],
|
|
2350
|
+
writablePerpMarketIndexes: [marketIndex],
|
|
2351
|
+
writableSpotMarketIndexes: [QUOTE_SPOT_MARKET_INDEX],
|
|
2653
2352
|
});
|
|
2654
2353
|
|
|
2655
|
-
const remainingAccounts = [
|
|
2656
|
-
...oracleAccountMap.values(),
|
|
2657
|
-
...spotMarketAccountMap.values(),
|
|
2658
|
-
...marketAccountMap.values(),
|
|
2659
|
-
];
|
|
2660
|
-
|
|
2661
2354
|
return await this.program.instruction.settleExpiredPosition(marketIndex, {
|
|
2662
2355
|
accounts: {
|
|
2663
2356
|
state: await this.getStatePublicKey(),
|
|
@@ -2704,9 +2397,10 @@ export class ClearingHouse {
|
|
|
2704
2397
|
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
2705
2398
|
const liquidatorStatsPublicKey = this.getUserStatsAccountPublicKey();
|
|
2706
2399
|
|
|
2707
|
-
const remainingAccounts = this.
|
|
2708
|
-
|
|
2709
|
-
|
|
2400
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
2401
|
+
userAccounts: [this.getUserAccount(), userAccount],
|
|
2402
|
+
useMarketLastSlotCache: true,
|
|
2403
|
+
writablePerpMarketIndexes: [marketIndex],
|
|
2710
2404
|
});
|
|
2711
2405
|
|
|
2712
2406
|
return await this.program.instruction.liquidatePerp(
|
|
@@ -2726,7 +2420,7 @@ export class ClearingHouse {
|
|
|
2726
2420
|
);
|
|
2727
2421
|
}
|
|
2728
2422
|
|
|
2729
|
-
public async
|
|
2423
|
+
public async liquidateSpot(
|
|
2730
2424
|
userAccountPublicKey: PublicKey,
|
|
2731
2425
|
userAccount: UserAccount,
|
|
2732
2426
|
assetMarketIndex: number,
|
|
@@ -2735,7 +2429,7 @@ export class ClearingHouse {
|
|
|
2735
2429
|
): Promise<TransactionSignature> {
|
|
2736
2430
|
const { txSig } = await this.txSender.send(
|
|
2737
2431
|
wrapInTx(
|
|
2738
|
-
await this.
|
|
2432
|
+
await this.getLiquidateSpotIx(
|
|
2739
2433
|
userAccountPublicKey,
|
|
2740
2434
|
userAccount,
|
|
2741
2435
|
assetMarketIndex,
|
|
@@ -2749,21 +2443,28 @@ export class ClearingHouse {
|
|
|
2749
2443
|
return txSig;
|
|
2750
2444
|
}
|
|
2751
2445
|
|
|
2752
|
-
public async
|
|
2446
|
+
public async getLiquidateSpotIx(
|
|
2753
2447
|
userAccountPublicKey: PublicKey,
|
|
2754
2448
|
userAccount: UserAccount,
|
|
2755
2449
|
assetMarketIndex: number,
|
|
2756
2450
|
liabilityMarketIndex: number,
|
|
2757
2451
|
maxLiabilityTransfer: BN
|
|
2758
2452
|
): Promise<TransactionInstruction> {
|
|
2453
|
+
const userStatsPublicKey = getUserStatsAccountPublicKey(
|
|
2454
|
+
this.program.programId,
|
|
2455
|
+
userAccount.authority
|
|
2456
|
+
);
|
|
2457
|
+
|
|
2759
2458
|
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
2459
|
+
const liquidatorStatsPublicKey = await this.getUserStatsAccountPublicKey();
|
|
2760
2460
|
|
|
2761
|
-
const remainingAccounts = this.
|
|
2762
|
-
|
|
2461
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
2462
|
+
userAccounts: [this.getUserAccount(), userAccount],
|
|
2463
|
+
useMarketLastSlotCache: true,
|
|
2763
2464
|
writableSpotMarketIndexes: [liabilityMarketIndex, assetMarketIndex],
|
|
2764
2465
|
});
|
|
2765
2466
|
|
|
2766
|
-
return await this.program.instruction.
|
|
2467
|
+
return await this.program.instruction.liquidateSpot(
|
|
2767
2468
|
assetMarketIndex,
|
|
2768
2469
|
liabilityMarketIndex,
|
|
2769
2470
|
maxLiabilityTransfer,
|
|
@@ -2772,7 +2473,9 @@ export class ClearingHouse {
|
|
|
2772
2473
|
state: await this.getStatePublicKey(),
|
|
2773
2474
|
authority: this.wallet.publicKey,
|
|
2774
2475
|
user: userAccountPublicKey,
|
|
2476
|
+
userStats: userStatsPublicKey,
|
|
2775
2477
|
liquidator: liquidatorPublicKey,
|
|
2478
|
+
liquidatorStats: liquidatorStatsPublicKey,
|
|
2776
2479
|
},
|
|
2777
2480
|
remainingAccounts: remainingAccounts,
|
|
2778
2481
|
}
|
|
@@ -2810,11 +2513,17 @@ export class ClearingHouse {
|
|
|
2810
2513
|
liabilityMarketIndex: number,
|
|
2811
2514
|
maxLiabilityTransfer: BN
|
|
2812
2515
|
): Promise<TransactionInstruction> {
|
|
2516
|
+
const userStatsPublicKey = getUserStatsAccountPublicKey(
|
|
2517
|
+
this.program.programId,
|
|
2518
|
+
userAccount.authority
|
|
2519
|
+
);
|
|
2520
|
+
|
|
2813
2521
|
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
2522
|
+
const liquidatorStatsPublicKey = await this.getUserStatsAccountPublicKey();
|
|
2814
2523
|
|
|
2815
|
-
const remainingAccounts = this.
|
|
2816
|
-
|
|
2817
|
-
|
|
2524
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
2525
|
+
userAccounts: [this.getUserAccount(), userAccount],
|
|
2526
|
+
writablePerpMarketIndexes: [perpMarketIndex],
|
|
2818
2527
|
writableSpotMarketIndexes: [liabilityMarketIndex],
|
|
2819
2528
|
});
|
|
2820
2529
|
|
|
@@ -2827,7 +2536,9 @@ export class ClearingHouse {
|
|
|
2827
2536
|
state: await this.getStatePublicKey(),
|
|
2828
2537
|
authority: this.wallet.publicKey,
|
|
2829
2538
|
user: userAccountPublicKey,
|
|
2539
|
+
userStats: userStatsPublicKey,
|
|
2830
2540
|
liquidator: liquidatorPublicKey,
|
|
2541
|
+
liquidatorStats: liquidatorStatsPublicKey,
|
|
2831
2542
|
},
|
|
2832
2543
|
remainingAccounts: remainingAccounts,
|
|
2833
2544
|
}
|
|
@@ -2865,11 +2576,17 @@ export class ClearingHouse {
|
|
|
2865
2576
|
assetMarketIndex: number,
|
|
2866
2577
|
maxPnlTransfer: BN
|
|
2867
2578
|
): Promise<TransactionInstruction> {
|
|
2579
|
+
const userStatsPublicKey = getUserStatsAccountPublicKey(
|
|
2580
|
+
this.program.programId,
|
|
2581
|
+
userAccount.authority
|
|
2582
|
+
);
|
|
2583
|
+
|
|
2868
2584
|
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
2585
|
+
const liquidatorStatsPublicKey = await this.getUserStatsAccountPublicKey();
|
|
2869
2586
|
|
|
2870
|
-
const remainingAccounts = this.
|
|
2871
|
-
|
|
2872
|
-
|
|
2587
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
2588
|
+
userAccounts: [this.getUserAccount(), userAccount],
|
|
2589
|
+
writablePerpMarketIndexes: [perpMarketIndex],
|
|
2873
2590
|
writableSpotMarketIndexes: [assetMarketIndex],
|
|
2874
2591
|
});
|
|
2875
2592
|
|
|
@@ -2882,7 +2599,9 @@ export class ClearingHouse {
|
|
|
2882
2599
|
state: await this.getStatePublicKey(),
|
|
2883
2600
|
authority: this.wallet.publicKey,
|
|
2884
2601
|
user: userAccountPublicKey,
|
|
2602
|
+
userStats: userStatsPublicKey,
|
|
2885
2603
|
liquidator: liquidatorPublicKey,
|
|
2604
|
+
liquidatorStats: liquidatorStatsPublicKey,
|
|
2886
2605
|
},
|
|
2887
2606
|
remainingAccounts: remainingAccounts,
|
|
2888
2607
|
}
|
|
@@ -2913,12 +2632,18 @@ export class ClearingHouse {
|
|
|
2913
2632
|
userAccount: UserAccount,
|
|
2914
2633
|
marketIndex: number
|
|
2915
2634
|
): Promise<TransactionInstruction> {
|
|
2635
|
+
const userStatsPublicKey = getUserStatsAccountPublicKey(
|
|
2636
|
+
this.program.programId,
|
|
2637
|
+
userAccount.authority
|
|
2638
|
+
);
|
|
2639
|
+
|
|
2916
2640
|
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
2641
|
+
const liquidatorStatsPublicKey = await this.getUserStatsAccountPublicKey();
|
|
2917
2642
|
|
|
2918
|
-
const remainingAccounts = this.
|
|
2919
|
-
|
|
2643
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
2644
|
+
userAccounts: [this.getUserAccount(), userAccount],
|
|
2645
|
+
writablePerpMarketIndexes: [marketIndex],
|
|
2920
2646
|
writableSpotMarketIndexes: [QUOTE_SPOT_MARKET_INDEX],
|
|
2921
|
-
counterPartyUserAccount: userAccount,
|
|
2922
2647
|
});
|
|
2923
2648
|
|
|
2924
2649
|
const spotMarket = this.getSpotMarketAccount(marketIndex);
|
|
@@ -2931,7 +2656,9 @@ export class ClearingHouse {
|
|
|
2931
2656
|
state: await this.getStatePublicKey(),
|
|
2932
2657
|
authority: this.wallet.publicKey,
|
|
2933
2658
|
user: userAccountPublicKey,
|
|
2659
|
+
userStats: userStatsPublicKey,
|
|
2934
2660
|
liquidator: liquidatorPublicKey,
|
|
2661
|
+
liquidatorStats: liquidatorStatsPublicKey,
|
|
2935
2662
|
spotMarketVault: spotMarket.vault,
|
|
2936
2663
|
insuranceFundVault: spotMarket.insuranceFundVault,
|
|
2937
2664
|
clearingHouseSigner: this.getSignerPublicKey(),
|
|
@@ -2942,14 +2669,14 @@ export class ClearingHouse {
|
|
|
2942
2669
|
);
|
|
2943
2670
|
}
|
|
2944
2671
|
|
|
2945
|
-
public async
|
|
2672
|
+
public async resolveSpotBankruptcy(
|
|
2946
2673
|
userAccountPublicKey: PublicKey,
|
|
2947
2674
|
userAccount: UserAccount,
|
|
2948
2675
|
marketIndex: number
|
|
2949
2676
|
): Promise<TransactionSignature> {
|
|
2950
2677
|
const { txSig } = await this.txSender.send(
|
|
2951
2678
|
wrapInTx(
|
|
2952
|
-
await this.
|
|
2679
|
+
await this.getResolveSpotBankruptcyIx(
|
|
2953
2680
|
userAccountPublicKey,
|
|
2954
2681
|
userAccount,
|
|
2955
2682
|
marketIndex
|
|
@@ -2961,25 +2688,33 @@ export class ClearingHouse {
|
|
|
2961
2688
|
return txSig;
|
|
2962
2689
|
}
|
|
2963
2690
|
|
|
2964
|
-
public async
|
|
2691
|
+
public async getResolveSpotBankruptcyIx(
|
|
2965
2692
|
userAccountPublicKey: PublicKey,
|
|
2966
2693
|
userAccount: UserAccount,
|
|
2967
2694
|
marketIndex: number
|
|
2968
2695
|
): Promise<TransactionInstruction> {
|
|
2696
|
+
const userStatsPublicKey = getUserStatsAccountPublicKey(
|
|
2697
|
+
this.program.programId,
|
|
2698
|
+
userAccount.authority
|
|
2699
|
+
);
|
|
2700
|
+
|
|
2969
2701
|
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
2702
|
+
const liquidatorStatsPublicKey = await this.getUserStatsAccountPublicKey();
|
|
2970
2703
|
|
|
2971
|
-
const remainingAccounts = this.
|
|
2704
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
2705
|
+
userAccounts: [this.getUserAccount(), userAccount],
|
|
2972
2706
|
writableSpotMarketIndexes: [marketIndex],
|
|
2973
|
-
counterPartyUserAccount: userAccount,
|
|
2974
2707
|
});
|
|
2975
2708
|
|
|
2976
2709
|
const spotMarket = this.getSpotMarketAccount(marketIndex);
|
|
2977
2710
|
|
|
2978
|
-
return await this.program.instruction.
|
|
2711
|
+
return await this.program.instruction.resolveSpotBankruptcy(marketIndex, {
|
|
2979
2712
|
accounts: {
|
|
2980
2713
|
state: await this.getStatePublicKey(),
|
|
2981
2714
|
authority: this.wallet.publicKey,
|
|
2982
2715
|
user: userAccountPublicKey,
|
|
2716
|
+
userStats: userStatsPublicKey,
|
|
2717
|
+
liquidatorStats: liquidatorStatsPublicKey,
|
|
2983
2718
|
liquidator: liquidatorPublicKey,
|
|
2984
2719
|
spotMarketVault: spotMarket.vault,
|
|
2985
2720
|
insuranceFundVault: spotMarket.insuranceFundVault,
|
|
@@ -2990,153 +2725,6 @@ export class ClearingHouse {
|
|
|
2990
2725
|
});
|
|
2991
2726
|
}
|
|
2992
2727
|
|
|
2993
|
-
getRemainingAccountsWithCounterparty(params: {
|
|
2994
|
-
counterPartyUserAccount: UserAccount;
|
|
2995
|
-
writablePerpMarketIndex?: number;
|
|
2996
|
-
writableSpotMarketIndexes?: number[];
|
|
2997
|
-
}): AccountMeta[] {
|
|
2998
|
-
const counterPartyUserAccount = params.counterPartyUserAccount;
|
|
2999
|
-
|
|
3000
|
-
const oracleAccountMap = new Map<string, AccountMeta>();
|
|
3001
|
-
const spotMarketAccountMap = new Map<number, AccountMeta>();
|
|
3002
|
-
const marketAccountMap = new Map<number, AccountMeta>();
|
|
3003
|
-
for (const spotPosition of counterPartyUserAccount.spotPositions) {
|
|
3004
|
-
if (!isSpotPositionAvailable(spotPosition)) {
|
|
3005
|
-
const spotMarket = this.getSpotMarketAccount(spotPosition.marketIndex);
|
|
3006
|
-
spotMarketAccountMap.set(spotPosition.marketIndex, {
|
|
3007
|
-
pubkey: spotMarket.pubkey,
|
|
3008
|
-
isSigner: false,
|
|
3009
|
-
isWritable: false,
|
|
3010
|
-
});
|
|
3011
|
-
|
|
3012
|
-
if (!spotMarket.oracle.equals(PublicKey.default)) {
|
|
3013
|
-
oracleAccountMap.set(spotMarket.oracle.toString(), {
|
|
3014
|
-
pubkey: spotMarket.oracle,
|
|
3015
|
-
isSigner: false,
|
|
3016
|
-
isWritable: false,
|
|
3017
|
-
});
|
|
3018
|
-
}
|
|
3019
|
-
}
|
|
3020
|
-
}
|
|
3021
|
-
for (const position of counterPartyUserAccount.perpPositions) {
|
|
3022
|
-
if (!positionIsAvailable(position)) {
|
|
3023
|
-
const market = this.getPerpMarketAccount(position.marketIndex);
|
|
3024
|
-
marketAccountMap.set(position.marketIndex, {
|
|
3025
|
-
pubkey: market.pubkey,
|
|
3026
|
-
isWritable: false,
|
|
3027
|
-
isSigner: false,
|
|
3028
|
-
});
|
|
3029
|
-
oracleAccountMap.set(market.amm.oracle.toString(), {
|
|
3030
|
-
pubkey: market.amm.oracle,
|
|
3031
|
-
isWritable: false,
|
|
3032
|
-
isSigner: false,
|
|
3033
|
-
});
|
|
3034
|
-
}
|
|
3035
|
-
}
|
|
3036
|
-
|
|
3037
|
-
const userAccountAndSlot = this.getUserAccountAndSlot();
|
|
3038
|
-
if (!userAccountAndSlot) {
|
|
3039
|
-
throw Error(
|
|
3040
|
-
'No user account found. Most likely user account does not exist or failed to fetch account'
|
|
3041
|
-
);
|
|
3042
|
-
}
|
|
3043
|
-
const { data: userAccount, slot: lastUserPositionsSlot } =
|
|
3044
|
-
userAccountAndSlot;
|
|
3045
|
-
|
|
3046
|
-
for (const [marketIndexNum, slot] of this.marketLastSlotCache.entries()) {
|
|
3047
|
-
// if cache has more recent slot than user positions account slot, add market to remaining accounts
|
|
3048
|
-
// otherwise remove from slot
|
|
3049
|
-
if (slot > lastUserPositionsSlot) {
|
|
3050
|
-
const marketAccount = this.getPerpMarketAccount(marketIndexNum);
|
|
3051
|
-
marketAccountMap.set(marketIndexNum, {
|
|
3052
|
-
pubkey: marketAccount.pubkey,
|
|
3053
|
-
isSigner: false,
|
|
3054
|
-
isWritable: false,
|
|
3055
|
-
});
|
|
3056
|
-
oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
|
|
3057
|
-
pubkey: marketAccount.amm.oracle,
|
|
3058
|
-
isSigner: false,
|
|
3059
|
-
isWritable: false,
|
|
3060
|
-
});
|
|
3061
|
-
} else {
|
|
3062
|
-
this.marketLastSlotCache.delete(marketIndexNum);
|
|
3063
|
-
}
|
|
3064
|
-
}
|
|
3065
|
-
for (const spotPosition of userAccount.spotPositions) {
|
|
3066
|
-
if (!isSpotPositionAvailable(spotPosition)) {
|
|
3067
|
-
const spotMarket = this.getSpotMarketAccount(spotPosition.marketIndex);
|
|
3068
|
-
spotMarketAccountMap.set(spotPosition.marketIndex, {
|
|
3069
|
-
pubkey: spotMarket.pubkey,
|
|
3070
|
-
isSigner: false,
|
|
3071
|
-
isWritable: false,
|
|
3072
|
-
});
|
|
3073
|
-
|
|
3074
|
-
if (!spotMarket.oracle.equals(PublicKey.default)) {
|
|
3075
|
-
oracleAccountMap.set(spotMarket.oracle.toString(), {
|
|
3076
|
-
pubkey: spotMarket.oracle,
|
|
3077
|
-
isSigner: false,
|
|
3078
|
-
isWritable: false,
|
|
3079
|
-
});
|
|
3080
|
-
}
|
|
3081
|
-
}
|
|
3082
|
-
}
|
|
3083
|
-
for (const position of userAccount.perpPositions) {
|
|
3084
|
-
if (!positionIsAvailable(position)) {
|
|
3085
|
-
const market = this.getPerpMarketAccount(position.marketIndex);
|
|
3086
|
-
marketAccountMap.set(position.marketIndex, {
|
|
3087
|
-
pubkey: market.pubkey,
|
|
3088
|
-
isWritable: false,
|
|
3089
|
-
isSigner: false,
|
|
3090
|
-
});
|
|
3091
|
-
oracleAccountMap.set(market.amm.oracle.toString(), {
|
|
3092
|
-
pubkey: market.amm.oracle,
|
|
3093
|
-
isWritable: false,
|
|
3094
|
-
isSigner: false,
|
|
3095
|
-
});
|
|
3096
|
-
}
|
|
3097
|
-
}
|
|
3098
|
-
|
|
3099
|
-
if (params.writablePerpMarketIndex !== undefined) {
|
|
3100
|
-
const market = this.getPerpMarketAccount(params.writablePerpMarketIndex);
|
|
3101
|
-
marketAccountMap.set(market.marketIndex, {
|
|
3102
|
-
pubkey: market.pubkey,
|
|
3103
|
-
isSigner: false,
|
|
3104
|
-
isWritable: true,
|
|
3105
|
-
});
|
|
3106
|
-
oracleAccountMap.set(market.amm.oracle.toString(), {
|
|
3107
|
-
pubkey: market.amm.oracle,
|
|
3108
|
-
isSigner: false,
|
|
3109
|
-
isWritable: false,
|
|
3110
|
-
});
|
|
3111
|
-
}
|
|
3112
|
-
|
|
3113
|
-
if (params.writableSpotMarketIndexes !== undefined) {
|
|
3114
|
-
for (const writableSpotMarketIndex of params.writableSpotMarketIndexes) {
|
|
3115
|
-
const spotMarketAccount = this.getSpotMarketAccount(
|
|
3116
|
-
writableSpotMarketIndex
|
|
3117
|
-
);
|
|
3118
|
-
spotMarketAccountMap.set(spotMarketAccount.marketIndex, {
|
|
3119
|
-
pubkey: spotMarketAccount.pubkey,
|
|
3120
|
-
isSigner: false,
|
|
3121
|
-
isWritable: true,
|
|
3122
|
-
});
|
|
3123
|
-
if (!spotMarketAccount.oracle.equals(PublicKey.default)) {
|
|
3124
|
-
oracleAccountMap.set(spotMarketAccount.oracle.toString(), {
|
|
3125
|
-
pubkey: spotMarketAccount.oracle,
|
|
3126
|
-
isSigner: false,
|
|
3127
|
-
isWritable: false,
|
|
3128
|
-
});
|
|
3129
|
-
}
|
|
3130
|
-
}
|
|
3131
|
-
}
|
|
3132
|
-
|
|
3133
|
-
return [
|
|
3134
|
-
...oracleAccountMap.values(),
|
|
3135
|
-
...spotMarketAccountMap.values(),
|
|
3136
|
-
...marketAccountMap.values(),
|
|
3137
|
-
];
|
|
3138
|
-
}
|
|
3139
|
-
|
|
3140
2728
|
public async updateFundingRate(
|
|
3141
2729
|
oracle: PublicKey,
|
|
3142
2730
|
marketIndex: number
|
|
@@ -3163,10 +2751,10 @@ export class ClearingHouse {
|
|
|
3163
2751
|
}
|
|
3164
2752
|
|
|
3165
2753
|
public async settleFundingPayment(
|
|
3166
|
-
|
|
2754
|
+
userAccountPublicKey: PublicKey
|
|
3167
2755
|
): Promise<TransactionSignature> {
|
|
3168
2756
|
const { txSig } = await this.txSender.send(
|
|
3169
|
-
wrapInTx(await this.getSettleFundingPaymentIx(
|
|
2757
|
+
wrapInTx(await this.getSettleFundingPaymentIx(userAccountPublicKey)),
|
|
3170
2758
|
[],
|
|
3171
2759
|
this.opts
|
|
3172
2760
|
);
|
|
@@ -3174,33 +2762,28 @@ export class ClearingHouse {
|
|
|
3174
2762
|
}
|
|
3175
2763
|
|
|
3176
2764
|
public async getSettleFundingPaymentIx(
|
|
3177
|
-
|
|
2765
|
+
userAccountPublicKey: PublicKey
|
|
3178
2766
|
): Promise<TransactionInstruction> {
|
|
3179
|
-
const
|
|
3180
|
-
|
|
2767
|
+
const userAccount = (await this.program.account.user.fetch(
|
|
2768
|
+
userAccountPublicKey
|
|
3181
2769
|
)) as UserAccount;
|
|
3182
2770
|
|
|
3183
|
-
const
|
|
3184
|
-
|
|
3185
|
-
const remainingAccounts = [];
|
|
3186
|
-
for (const position of userPositions) {
|
|
2771
|
+
const writablePerpMarketIndexes = [];
|
|
2772
|
+
for (const position of userAccount.perpPositions) {
|
|
3187
2773
|
if (!positionIsAvailable(position)) {
|
|
3188
|
-
|
|
3189
|
-
this.program.programId,
|
|
3190
|
-
position.marketIndex
|
|
3191
|
-
);
|
|
3192
|
-
remainingAccounts.push({
|
|
3193
|
-
pubkey: marketPublicKey,
|
|
3194
|
-
isWritable: false,
|
|
3195
|
-
isSigner: false,
|
|
3196
|
-
});
|
|
2774
|
+
writablePerpMarketIndexes.push(position.marketIndex);
|
|
3197
2775
|
}
|
|
3198
2776
|
}
|
|
3199
2777
|
|
|
2778
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
2779
|
+
userAccounts: [userAccount],
|
|
2780
|
+
writablePerpMarketIndexes,
|
|
2781
|
+
});
|
|
2782
|
+
|
|
3200
2783
|
return await this.program.instruction.settleFundingPayment({
|
|
3201
2784
|
accounts: {
|
|
3202
2785
|
state: await this.getStatePublicKey(),
|
|
3203
|
-
user:
|
|
2786
|
+
user: userAccountPublicKey,
|
|
3204
2787
|
},
|
|
3205
2788
|
remainingAccounts,
|
|
3206
2789
|
});
|
|
@@ -3274,7 +2857,9 @@ export class ClearingHouse {
|
|
|
3274
2857
|
);
|
|
3275
2858
|
|
|
3276
2859
|
const remainingAccounts = this.getRemainingAccounts({
|
|
3277
|
-
|
|
2860
|
+
userAccounts: [this.getUserAccount()],
|
|
2861
|
+
useMarketLastSlotCache: true,
|
|
2862
|
+
writableSpotMarketIndexes: [marketIndex],
|
|
3278
2863
|
});
|
|
3279
2864
|
|
|
3280
2865
|
return await this.program.rpc.addInsuranceFundStake(marketIndex, amount, {
|
|
@@ -3284,7 +2869,9 @@ export class ClearingHouse {
|
|
|
3284
2869
|
insuranceFundStake: ifStakeAccountPublicKey,
|
|
3285
2870
|
userStats: this.getUserStatsAccountPublicKey(),
|
|
3286
2871
|
authority: this.wallet.publicKey,
|
|
2872
|
+
spotMarketVault: spotMarket.vault,
|
|
3287
2873
|
insuranceFundVault: spotMarket.insuranceFundVault,
|
|
2874
|
+
clearingHouseSigner: this.getSignerPublicKey(),
|
|
3288
2875
|
userTokenAccount: collateralAccountPublicKey,
|
|
3289
2876
|
tokenProgram: TOKEN_PROGRAM_ID,
|
|
3290
2877
|
},
|
|
@@ -3304,7 +2891,9 @@ export class ClearingHouse {
|
|
|
3304
2891
|
);
|
|
3305
2892
|
|
|
3306
2893
|
const remainingAccounts = this.getRemainingAccounts({
|
|
3307
|
-
|
|
2894
|
+
userAccounts: [this.getUserAccount()],
|
|
2895
|
+
useMarketLastSlotCache: true,
|
|
2896
|
+
writableSpotMarketIndexes: [marketIndex],
|
|
3308
2897
|
});
|
|
3309
2898
|
|
|
3310
2899
|
return await this.program.rpc.requestRemoveInsuranceFundStake(
|
|
@@ -3318,8 +2907,6 @@ export class ClearingHouse {
|
|
|
3318
2907
|
userStats: this.getUserStatsAccountPublicKey(),
|
|
3319
2908
|
authority: this.wallet.publicKey,
|
|
3320
2909
|
insuranceFundVault: spotMarketAccount.insuranceFundVault,
|
|
3321
|
-
// userTokenAccount: collateralAccountPublicKey,
|
|
3322
|
-
// tokenProgram: TOKEN_PROGRAM_ID,
|
|
3323
2910
|
},
|
|
3324
2911
|
remainingAccounts,
|
|
3325
2912
|
}
|
|
@@ -3337,7 +2924,9 @@ export class ClearingHouse {
|
|
|
3337
2924
|
);
|
|
3338
2925
|
|
|
3339
2926
|
const remainingAccounts = this.getRemainingAccounts({
|
|
3340
|
-
|
|
2927
|
+
userAccounts: [this.getUserAccount()],
|
|
2928
|
+
useMarketLastSlotCache: true,
|
|
2929
|
+
writableSpotMarketIndexes: [marketIndex],
|
|
3341
2930
|
});
|
|
3342
2931
|
|
|
3343
2932
|
return await this.program.rpc.cancelRequestRemoveInsuranceFundStake(
|
|
@@ -3350,8 +2939,6 @@ export class ClearingHouse {
|
|
|
3350
2939
|
userStats: this.getUserStatsAccountPublicKey(),
|
|
3351
2940
|
authority: this.wallet.publicKey,
|
|
3352
2941
|
insuranceFundVault: spotMarketAccount.insuranceFundVault,
|
|
3353
|
-
// userTokenAccount: collateralAccountPublicKey,
|
|
3354
|
-
// tokenProgram: TOKEN_PROGRAM_ID,
|
|
3355
2942
|
},
|
|
3356
2943
|
remainingAccounts,
|
|
3357
2944
|
}
|
|
@@ -3370,7 +2957,9 @@ export class ClearingHouse {
|
|
|
3370
2957
|
);
|
|
3371
2958
|
|
|
3372
2959
|
const remainingAccounts = this.getRemainingAccounts({
|
|
3373
|
-
|
|
2960
|
+
userAccounts: [this.getUserAccount()],
|
|
2961
|
+
useMarketLastSlotCache: true,
|
|
2962
|
+
writableSpotMarketIndexes: [marketIndex],
|
|
3374
2963
|
});
|
|
3375
2964
|
|
|
3376
2965
|
return await this.program.rpc.removeInsuranceFundStake(marketIndex, {
|
|
@@ -3395,7 +2984,9 @@ export class ClearingHouse {
|
|
|
3395
2984
|
const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
|
|
3396
2985
|
|
|
3397
2986
|
const remainingAccounts = this.getRemainingAccounts({
|
|
3398
|
-
|
|
2987
|
+
userAccounts: [this.getUserAccount()],
|
|
2988
|
+
useMarketLastSlotCache: true,
|
|
2989
|
+
writableSpotMarketIndexes: [marketIndex],
|
|
3399
2990
|
});
|
|
3400
2991
|
|
|
3401
2992
|
return await this.program.rpc.settleRevenueToInsuranceFund(marketIndex, {
|
|
@@ -3430,8 +3021,10 @@ export class ClearingHouse {
|
|
|
3430
3021
|
perpMarketIndex: number
|
|
3431
3022
|
): Promise<TransactionInstruction> {
|
|
3432
3023
|
const remainingAccounts = this.getRemainingAccounts({
|
|
3433
|
-
|
|
3434
|
-
|
|
3024
|
+
userAccounts: [this.getUserAccount()],
|
|
3025
|
+
useMarketLastSlotCache: true,
|
|
3026
|
+
writablePerpMarketIndexes: [perpMarketIndex],
|
|
3027
|
+
writableSpotMarketIndexes: [spotMarketIndex],
|
|
3435
3028
|
});
|
|
3436
3029
|
|
|
3437
3030
|
const spotMarket = this.getSpotMarketAccount(spotMarketIndex);
|