@drift-labs/sdk 0.2.0-temp.0 → 0.2.0-temp.1
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 +7 -5
- package/lib/admin.js +34 -11
- package/lib/clearingHouse.d.ts +23 -9
- package/lib/clearingHouse.js +335 -95
- package/lib/clearingHouseUser.d.ts +2 -2
- package/lib/clearingHouseUser.js +8 -17
- package/lib/config.js +1 -1
- package/lib/constants/banks.js +9 -2
- package/lib/constants/numericConstants.d.ts +1 -0
- package/lib/constants/numericConstants.js +2 -1
- package/lib/idl/clearing_house.json +689 -153
- package/lib/idl/{mock_usdc_faucet.json → token_faucet.json} +46 -23
- package/lib/index.d.ts +3 -2
- package/lib/index.js +7 -2
- package/lib/math/amm.js +7 -35
- package/lib/math/auction.js +4 -1
- package/lib/math/orders.d.ts +2 -2
- package/lib/math/orders.js +19 -2
- package/lib/math/position.js +3 -1
- package/lib/math/trade.d.ts +1 -1
- package/lib/math/trade.js +7 -10
- package/lib/orderParams.d.ts +14 -5
- package/lib/orderParams.js +8 -96
- package/lib/orders.js +1 -1
- package/lib/slot/SlotSubscriber.d.ts +7 -0
- package/lib/slot/SlotSubscriber.js +3 -0
- package/lib/{mockUSDCFaucet.d.ts → tokenFaucet.d.ts} +7 -5
- package/lib/{mockUSDCFaucet.js → tokenFaucet.js} +41 -40
- package/lib/tx/utils.js +1 -1
- package/lib/types.d.ts +132 -14
- package/lib/types.js +52 -1
- package/lib/util/computeUnits.js +1 -1
- package/package.json +3 -3
- package/src/accounts/bulkAccountLoader.js +197 -0
- package/src/accounts/bulkUserSubscription.js +33 -0
- package/src/accounts/pollingClearingHouseAccountSubscriber.js +311 -0
- package/src/accounts/pollingOracleSubscriber.js +93 -0
- package/src/accounts/pollingTokenAccountSubscriber.js +90 -0
- package/src/accounts/pollingUserAccountSubscriber.js +132 -0
- package/src/accounts/types.js +10 -0
- package/src/accounts/utils.js +7 -0
- package/src/accounts/webSocketAccountSubscriber.js +93 -0
- package/src/accounts/webSocketClearingHouseAccountSubscriber.js +233 -0
- package/src/accounts/webSocketUserAccountSubscriber.js +62 -0
- package/src/addresses/marketAddresses.js +26 -0
- package/src/admin.js +517 -0
- package/src/admin.ts +53 -14
- package/src/assert/assert.js +9 -0
- package/src/clearingHouse.ts +510 -131
- package/src/clearingHouseConfig.js +2 -0
- package/src/clearingHouseUser.ts +12 -23
- package/src/clearingHouseUserConfig.js +2 -0
- package/src/config.js +67 -0
- package/src/config.ts +1 -1
- package/src/constants/banks.js +42 -0
- package/src/constants/banks.ts +9 -2
- package/src/constants/markets.js +42 -0
- package/src/constants/numericConstants.js +41 -0
- package/src/constants/numericConstants.ts +1 -0
- package/src/events/eventList.js +77 -0
- package/src/events/eventSubscriber.js +139 -0
- package/src/events/fetchLogs.js +50 -0
- package/src/events/pollingLogProvider.js +64 -0
- package/src/events/sort.js +44 -0
- package/src/events/txEventCache.js +71 -0
- package/src/events/types.js +20 -0
- package/src/events/webSocketLogProvider.js +41 -0
- package/src/examples/makeTradeExample.js +80 -0
- package/src/factory/bigNum.js +390 -0
- package/src/factory/oracleClient.js +20 -0
- package/src/idl/clearing_house.json +689 -153
- package/src/idl/{mock_usdc_faucet.json → token_faucet.json} +46 -23
- package/src/index.js +69 -0
- package/src/index.ts +3 -2
- package/src/math/amm.js +369 -0
- package/src/math/amm.ts +19 -49
- package/src/math/auction.js +42 -0
- package/src/math/auction.ts +5 -1
- package/src/math/conversion.js +11 -0
- package/src/math/funding.js +248 -0
- package/src/math/oracles.js +26 -0
- package/src/math/orders.ts +17 -3
- package/src/math/position.ts +5 -1
- package/src/math/repeg.js +128 -0
- package/src/math/state.js +15 -0
- package/src/math/trade.js +253 -0
- package/src/math/trade.ts +23 -25
- package/src/math/utils.js +0 -1
- package/src/mockUSDCFaucet.js +280 -0
- package/src/oracles/oracleClientCache.js +19 -0
- package/src/oracles/pythClient.js +46 -0
- package/src/oracles/quoteAssetOracleClient.js +32 -0
- package/src/oracles/switchboardClient.js +69 -0
- package/src/oracles/types.js +2 -0
- package/src/orderParams.js +20 -0
- package/src/orderParams.ts +20 -141
- package/src/orders.ts +2 -1
- package/src/slot/SlotSubscriber.js +39 -0
- package/src/slot/SlotSubscriber.ts +11 -1
- package/src/token/index.js +38 -0
- package/src/tokenFaucet.js +189 -0
- package/src/{mockUSDCFaucet.ts → tokenFaucet.ts} +48 -59
- package/src/tx/types.js +2 -0
- package/src/tx/utils.js +17 -0
- package/src/tx/utils.ts +1 -1
- package/src/types.js +125 -0
- package/src/types.ts +128 -15
- package/src/userName.js +20 -0
- package/src/util/computeUnits.js +21 -11
- package/src/util/computeUnits.ts +1 -1
- package/src/util/getTokenAddress.js +9 -0
- package/src/util/promiseTimeout.js +14 -0
- package/src/util/tps.js +27 -0
- package/src/wallet.js +35 -0
- package/src/util/computeUnits.js.map +0 -1
package/src/clearingHouse.ts
CHANGED
|
@@ -11,6 +11,10 @@ import {
|
|
|
11
11
|
BankAccount,
|
|
12
12
|
UserBankBalance,
|
|
13
13
|
MakerInfo,
|
|
14
|
+
TakerInfo,
|
|
15
|
+
OptionalOrderParams,
|
|
16
|
+
DefaultOrderParams,
|
|
17
|
+
OrderType,
|
|
14
18
|
} from './types';
|
|
15
19
|
import * as anchor from '@project-serum/anchor';
|
|
16
20
|
import clearingHouseIDL from './idl/clearing_house.json';
|
|
@@ -25,7 +29,7 @@ import {
|
|
|
25
29
|
AccountMeta,
|
|
26
30
|
} from '@solana/web3.js';
|
|
27
31
|
|
|
28
|
-
import {
|
|
32
|
+
import { TokenFaucet } from './tokenFaucet';
|
|
29
33
|
import { EventEmitter } from 'events';
|
|
30
34
|
import StrictEventEmitter from 'strict-event-emitter-types';
|
|
31
35
|
import {
|
|
@@ -52,7 +56,6 @@ import { WebSocketClearingHouseAccountSubscriber } from './accounts/webSocketCle
|
|
|
52
56
|
import { RetryTxSender } from './tx/retryTxSender';
|
|
53
57
|
import { ClearingHouseUser } from './clearingHouseUser';
|
|
54
58
|
import { ClearingHouseUserAccountSubscriptionConfig } from './clearingHouseUserConfig';
|
|
55
|
-
import { getMarketOrderParams } from './orderParams';
|
|
56
59
|
import { getMarketsBanksAndOraclesForSubscription } from './config';
|
|
57
60
|
|
|
58
61
|
/**
|
|
@@ -561,13 +564,19 @@ export class ClearingHouse {
|
|
|
561
564
|
writableBankIndex: bankIndex,
|
|
562
565
|
});
|
|
563
566
|
} else {
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
+
const bankAccount = this.getBankAccount(bankIndex);
|
|
568
|
+
if (!bankAccount.oracle.equals(PublicKey.default)) {
|
|
569
|
+
remainingAccounts.push({
|
|
570
|
+
pubkey: bankAccount.oracle,
|
|
567
571
|
isSigner: false,
|
|
568
|
-
isWritable:
|
|
569
|
-
}
|
|
570
|
-
|
|
572
|
+
isWritable: false,
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
remainingAccounts.push({
|
|
576
|
+
pubkey: bankAccount.pubkey,
|
|
577
|
+
isSigner: false,
|
|
578
|
+
isWritable: true,
|
|
579
|
+
});
|
|
571
580
|
}
|
|
572
581
|
|
|
573
582
|
const bank = this.getBankAccount(bankIndex);
|
|
@@ -635,11 +644,12 @@ export class ClearingHouse {
|
|
|
635
644
|
public async initializeUserAccountForDevnet(
|
|
636
645
|
userId = 0,
|
|
637
646
|
name = DEFAULT_USER_NAME,
|
|
638
|
-
|
|
647
|
+
bankIndex: BN,
|
|
648
|
+
tokenFaucet: TokenFaucet,
|
|
639
649
|
amount: BN
|
|
640
650
|
): Promise<[TransactionSignature, PublicKey]> {
|
|
641
651
|
const [associateTokenPublicKey, createAssociatedAccountIx, mintToIx] =
|
|
642
|
-
await
|
|
652
|
+
await tokenFaucet.createAssociatedTokenAccountAndMintToInstructions(
|
|
643
653
|
this.wallet.publicKey,
|
|
644
654
|
amount
|
|
645
655
|
);
|
|
@@ -649,7 +659,7 @@ export class ClearingHouse {
|
|
|
649
659
|
|
|
650
660
|
const depositCollateralIx = await this.getDepositInstruction(
|
|
651
661
|
amount,
|
|
652
|
-
|
|
662
|
+
bankIndex,
|
|
653
663
|
associateTokenPublicKey,
|
|
654
664
|
userId,
|
|
655
665
|
false,
|
|
@@ -798,20 +808,17 @@ export class ClearingHouse {
|
|
|
798
808
|
marketIndex: BN,
|
|
799
809
|
limitPrice?: BN
|
|
800
810
|
): Promise<TransactionSignature> {
|
|
801
|
-
return await this.placeAndTake(
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
limitPrice
|
|
809
|
-
)
|
|
810
|
-
);
|
|
811
|
+
return await this.placeAndTake({
|
|
812
|
+
orderType: OrderType.MARKET,
|
|
813
|
+
marketIndex,
|
|
814
|
+
direction,
|
|
815
|
+
baseAssetAmount: amount,
|
|
816
|
+
price: limitPrice,
|
|
817
|
+
});
|
|
811
818
|
}
|
|
812
819
|
|
|
813
820
|
public async placeOrder(
|
|
814
|
-
orderParams:
|
|
821
|
+
orderParams: OptionalOrderParams
|
|
815
822
|
): Promise<TransactionSignature> {
|
|
816
823
|
const { txSig, slot } = await this.txSender.send(
|
|
817
824
|
wrapInTx(await this.getPlaceOrderIx(orderParams)),
|
|
@@ -822,9 +829,14 @@ export class ClearingHouse {
|
|
|
822
829
|
return txSig;
|
|
823
830
|
}
|
|
824
831
|
|
|
832
|
+
getOrderParams(optionalOrderParams: OptionalOrderParams): OrderParams {
|
|
833
|
+
return Object.assign({}, DefaultOrderParams, optionalOrderParams);
|
|
834
|
+
}
|
|
835
|
+
|
|
825
836
|
public async getPlaceOrderIx(
|
|
826
|
-
orderParams:
|
|
837
|
+
orderParams: OptionalOrderParams
|
|
827
838
|
): Promise<TransactionInstruction> {
|
|
839
|
+
orderParams = this.getOrderParams(orderParams);
|
|
828
840
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
829
841
|
|
|
830
842
|
const remainingAccounts = this.getRemainingAccounts({
|
|
@@ -967,48 +979,64 @@ export class ClearingHouse {
|
|
|
967
979
|
const marketIndex = order.marketIndex;
|
|
968
980
|
const marketAccount = this.getMarketAccount(marketIndex);
|
|
969
981
|
|
|
970
|
-
const
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
982
|
+
const oracleAccountMap = new Map<string, AccountMeta>();
|
|
983
|
+
const bankAccountMap = new Map<number, AccountMeta>();
|
|
984
|
+
const marketAccountMap = new Map<number, AccountMeta>();
|
|
985
|
+
|
|
986
|
+
marketAccountMap.set(marketIndex.toNumber(), {
|
|
987
|
+
pubkey: marketAccount.pubkey,
|
|
988
|
+
isWritable: true,
|
|
989
|
+
isSigner: false,
|
|
990
|
+
});
|
|
991
|
+
oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
|
|
992
|
+
pubkey: marketAccount.amm.oracle,
|
|
993
|
+
isWritable: false,
|
|
994
|
+
isSigner: false,
|
|
995
|
+
});
|
|
996
|
+
|
|
997
|
+
for (const bankBalance of userAccount.bankBalances) {
|
|
998
|
+
if (!bankBalance.balance.eq(ZERO)) {
|
|
999
|
+
const bankAccount = this.getBankAccount(bankBalance.bankIndex);
|
|
1000
|
+
bankAccountMap.set(bankBalance.bankIndex.toNumber(), {
|
|
1001
|
+
pubkey: bankAccount.pubkey,
|
|
1002
|
+
isSigner: false,
|
|
1003
|
+
isWritable: true,
|
|
1004
|
+
});
|
|
1005
|
+
|
|
1006
|
+
if (!bankAccount.oracle.equals(PublicKey.default)) {
|
|
1007
|
+
oracleAccountMap.set(bankAccount.oracle.toString(), {
|
|
1008
|
+
pubkey: bankAccount.oracle,
|
|
1009
|
+
isSigner: false,
|
|
1010
|
+
isWritable: false,
|
|
1011
|
+
});
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
|
|
991
1016
|
for (const position of userAccount.positions) {
|
|
992
1017
|
if (
|
|
993
1018
|
!positionIsAvailable(position) &&
|
|
994
1019
|
!position.marketIndex.eq(order.marketIndex)
|
|
995
1020
|
) {
|
|
996
1021
|
const market = this.getMarketAccount(position.marketIndex);
|
|
997
|
-
|
|
1022
|
+
marketAccountMap.set(position.marketIndex.toNumber(), {
|
|
998
1023
|
pubkey: market.pubkey,
|
|
999
1024
|
isWritable: true,
|
|
1000
1025
|
isSigner: false,
|
|
1001
1026
|
});
|
|
1002
|
-
|
|
1027
|
+
oracleAccountMap.set(market.amm.oracle.toString(), {
|
|
1003
1028
|
pubkey: market.amm.oracle,
|
|
1004
1029
|
isWritable: false,
|
|
1005
1030
|
isSigner: false,
|
|
1006
1031
|
});
|
|
1007
1032
|
}
|
|
1008
1033
|
}
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1034
|
+
|
|
1035
|
+
const remainingAccounts = [
|
|
1036
|
+
...oracleAccountMap.values(),
|
|
1037
|
+
...bankAccountMap.values(),
|
|
1038
|
+
...marketAccountMap.values(),
|
|
1039
|
+
];
|
|
1012
1040
|
|
|
1013
1041
|
if (makerInfo) {
|
|
1014
1042
|
remainingAccounts.push({
|
|
@@ -1020,6 +1048,7 @@ export class ClearingHouse {
|
|
|
1020
1048
|
|
|
1021
1049
|
const orderId = order.orderId;
|
|
1022
1050
|
const makerOrderId = makerInfo ? makerInfo.order.orderId : null;
|
|
1051
|
+
|
|
1023
1052
|
return await this.program.instruction.fillOrder(orderId, makerOrderId, {
|
|
1024
1053
|
accounts: {
|
|
1025
1054
|
state: await this.getStatePublicKey(),
|
|
@@ -1054,48 +1083,64 @@ export class ClearingHouse {
|
|
|
1054
1083
|
const marketIndex = order.marketIndex;
|
|
1055
1084
|
const marketAccount = this.getMarketAccount(marketIndex);
|
|
1056
1085
|
|
|
1057
|
-
const
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1086
|
+
const oracleAccountMap = new Map<string, AccountMeta>();
|
|
1087
|
+
const bankAccountMap = new Map<number, AccountMeta>();
|
|
1088
|
+
const marketAccountMap = new Map<number, AccountMeta>();
|
|
1089
|
+
|
|
1090
|
+
marketAccountMap.set(marketIndex.toNumber(), {
|
|
1091
|
+
pubkey: marketAccount.pubkey,
|
|
1092
|
+
isWritable: true,
|
|
1093
|
+
isSigner: false,
|
|
1094
|
+
});
|
|
1095
|
+
oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
|
|
1096
|
+
pubkey: marketAccount.amm.oracle,
|
|
1097
|
+
isWritable: false,
|
|
1098
|
+
isSigner: false,
|
|
1099
|
+
});
|
|
1100
|
+
|
|
1101
|
+
for (const bankBalance of userAccount.bankBalances) {
|
|
1102
|
+
if (!bankBalance.balance.eq(ZERO)) {
|
|
1103
|
+
const bankAccount = this.getBankAccount(bankBalance.bankIndex);
|
|
1104
|
+
bankAccountMap.set(bankBalance.bankIndex.toNumber(), {
|
|
1105
|
+
pubkey: bankAccount.pubkey,
|
|
1106
|
+
isSigner: false,
|
|
1107
|
+
isWritable: true,
|
|
1108
|
+
});
|
|
1109
|
+
|
|
1110
|
+
if (!bankAccount.oracle.equals(PublicKey.default)) {
|
|
1111
|
+
oracleAccountMap.set(bankAccount.oracle.toString(), {
|
|
1112
|
+
pubkey: bankAccount.oracle,
|
|
1113
|
+
isSigner: false,
|
|
1114
|
+
isWritable: false,
|
|
1115
|
+
});
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1078
1120
|
for (const position of userAccount.positions) {
|
|
1079
1121
|
if (
|
|
1080
1122
|
!positionIsAvailable(position) &&
|
|
1081
1123
|
!position.marketIndex.eq(order.marketIndex)
|
|
1082
1124
|
) {
|
|
1083
1125
|
const market = this.getMarketAccount(position.marketIndex);
|
|
1084
|
-
|
|
1126
|
+
marketAccountMap.set(position.marketIndex.toNumber(), {
|
|
1085
1127
|
pubkey: market.pubkey,
|
|
1086
|
-
isWritable:
|
|
1128
|
+
isWritable: true,
|
|
1087
1129
|
isSigner: false,
|
|
1088
1130
|
});
|
|
1089
|
-
|
|
1131
|
+
oracleAccountMap.set(market.amm.oracle.toString(), {
|
|
1090
1132
|
pubkey: market.amm.oracle,
|
|
1091
1133
|
isWritable: false,
|
|
1092
1134
|
isSigner: false,
|
|
1093
1135
|
});
|
|
1094
1136
|
}
|
|
1095
1137
|
}
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1138
|
+
|
|
1139
|
+
const remainingAccounts = [
|
|
1140
|
+
...oracleAccountMap.values(),
|
|
1141
|
+
...bankAccountMap.values(),
|
|
1142
|
+
...marketAccountMap.values(),
|
|
1143
|
+
];
|
|
1099
1144
|
|
|
1100
1145
|
const orderId = order.orderId;
|
|
1101
1146
|
return await this.program.instruction.triggerOrder(orderId, {
|
|
@@ -1110,7 +1155,7 @@ export class ClearingHouse {
|
|
|
1110
1155
|
}
|
|
1111
1156
|
|
|
1112
1157
|
public async placeAndTake(
|
|
1113
|
-
orderParams:
|
|
1158
|
+
orderParams: OptionalOrderParams,
|
|
1114
1159
|
makerInfo?: MakerInfo
|
|
1115
1160
|
): Promise<TransactionSignature> {
|
|
1116
1161
|
const { txSig, slot } = await this.txSender.send(
|
|
@@ -1123,9 +1168,10 @@ export class ClearingHouse {
|
|
|
1123
1168
|
}
|
|
1124
1169
|
|
|
1125
1170
|
public async getPlaceAndTakeIx(
|
|
1126
|
-
orderParams:
|
|
1171
|
+
orderParams: OptionalOrderParams,
|
|
1127
1172
|
makerInfo?: MakerInfo
|
|
1128
1173
|
): Promise<TransactionInstruction> {
|
|
1174
|
+
orderParams = this.getOrderParams(orderParams);
|
|
1129
1175
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
1130
1176
|
|
|
1131
1177
|
const remainingAccounts = this.getRemainingAccounts({
|
|
@@ -1157,6 +1203,55 @@ export class ClearingHouse {
|
|
|
1157
1203
|
);
|
|
1158
1204
|
}
|
|
1159
1205
|
|
|
1206
|
+
public async placeAndMake(
|
|
1207
|
+
orderParams: OptionalOrderParams,
|
|
1208
|
+
takerInfo: TakerInfo
|
|
1209
|
+
): Promise<TransactionSignature> {
|
|
1210
|
+
const { txSig, slot } = await this.txSender.send(
|
|
1211
|
+
wrapInTx(await this.getPlaceAndMakeIx(orderParams, takerInfo)),
|
|
1212
|
+
[],
|
|
1213
|
+
this.opts
|
|
1214
|
+
);
|
|
1215
|
+
|
|
1216
|
+
this.marketLastSlotCache.set(orderParams.marketIndex.toNumber(), slot);
|
|
1217
|
+
|
|
1218
|
+
return txSig;
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1221
|
+
public async getPlaceAndMakeIx(
|
|
1222
|
+
orderParams: OptionalOrderParams,
|
|
1223
|
+
takerInfo: TakerInfo
|
|
1224
|
+
): Promise<TransactionInstruction> {
|
|
1225
|
+
orderParams = this.getOrderParams(orderParams);
|
|
1226
|
+
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
1227
|
+
|
|
1228
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
1229
|
+
writableMarketIndex: orderParams.marketIndex,
|
|
1230
|
+
writableBankIndex: QUOTE_ASSET_BANK_INDEX,
|
|
1231
|
+
});
|
|
1232
|
+
|
|
1233
|
+
const takerOrderId = takerInfo!.order!.orderId;
|
|
1234
|
+
remainingAccounts.push({
|
|
1235
|
+
pubkey: takerInfo.taker,
|
|
1236
|
+
isSigner: false,
|
|
1237
|
+
isWritable: true,
|
|
1238
|
+
});
|
|
1239
|
+
|
|
1240
|
+
return await this.program.instruction.placeAndMake(
|
|
1241
|
+
orderParams,
|
|
1242
|
+
takerOrderId,
|
|
1243
|
+
{
|
|
1244
|
+
accounts: {
|
|
1245
|
+
state: await this.getStatePublicKey(),
|
|
1246
|
+
user: userAccountPublicKey,
|
|
1247
|
+
taker: takerInfo.taker,
|
|
1248
|
+
authority: this.wallet.publicKey,
|
|
1249
|
+
},
|
|
1250
|
+
remainingAccounts,
|
|
1251
|
+
}
|
|
1252
|
+
);
|
|
1253
|
+
}
|
|
1254
|
+
|
|
1160
1255
|
/**
|
|
1161
1256
|
* Close an entire position. If you want to reduce a position, use the {@link openPosition} method in the opposite direction of the current position.
|
|
1162
1257
|
* @param marketIndex
|
|
@@ -1168,16 +1263,13 @@ export class ClearingHouse {
|
|
|
1168
1263
|
throw Error(`No position in market ${marketIndex.toString()}`);
|
|
1169
1264
|
}
|
|
1170
1265
|
|
|
1171
|
-
return await this.placeAndTake(
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
undefined
|
|
1179
|
-
)
|
|
1180
|
-
);
|
|
1266
|
+
return await this.placeAndTake({
|
|
1267
|
+
orderType: OrderType.MARKET,
|
|
1268
|
+
marketIndex,
|
|
1269
|
+
direction: findDirectionToClose(userPosition),
|
|
1270
|
+
baseAssetAmount: userPosition.baseAssetAmount,
|
|
1271
|
+
reduceOnly: true,
|
|
1272
|
+
});
|
|
1181
1273
|
}
|
|
1182
1274
|
|
|
1183
1275
|
public async settlePNLs(
|
|
@@ -1299,72 +1391,359 @@ export class ClearingHouse {
|
|
|
1299
1391
|
});
|
|
1300
1392
|
}
|
|
1301
1393
|
|
|
1302
|
-
public async
|
|
1303
|
-
|
|
1394
|
+
public async liquidatePerp(
|
|
1395
|
+
userAccountPublicKey: PublicKey,
|
|
1396
|
+
userAccount: UserAccount,
|
|
1397
|
+
marketIndex: BN,
|
|
1398
|
+
maxBaseAssetAmount: BN
|
|
1304
1399
|
): Promise<TransactionSignature> {
|
|
1305
1400
|
const { txSig } = await this.txSender.send(
|
|
1306
|
-
wrapInTx(
|
|
1401
|
+
wrapInTx(
|
|
1402
|
+
await this.getLiquidatePerpIx(
|
|
1403
|
+
userAccountPublicKey,
|
|
1404
|
+
userAccount,
|
|
1405
|
+
marketIndex,
|
|
1406
|
+
maxBaseAssetAmount
|
|
1407
|
+
)
|
|
1408
|
+
),
|
|
1307
1409
|
[],
|
|
1308
1410
|
this.opts
|
|
1309
1411
|
);
|
|
1310
1412
|
return txSig;
|
|
1311
1413
|
}
|
|
1312
1414
|
|
|
1313
|
-
public async
|
|
1314
|
-
|
|
1415
|
+
public async getLiquidatePerpIx(
|
|
1416
|
+
userAccountPublicKey: PublicKey,
|
|
1417
|
+
userAccount: UserAccount,
|
|
1418
|
+
marketIndex: BN,
|
|
1419
|
+
maxBaseAssetAmount: BN
|
|
1315
1420
|
): Promise<TransactionInstruction> {
|
|
1316
|
-
const
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1421
|
+
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
1422
|
+
|
|
1423
|
+
const remainingAccounts = this.getRemainingAccountsForLiquidation({
|
|
1424
|
+
writableMarketIndex: marketIndex,
|
|
1425
|
+
userAccount,
|
|
1426
|
+
});
|
|
1320
1427
|
|
|
1321
|
-
|
|
1428
|
+
return await this.program.instruction.liquidatePerp(
|
|
1429
|
+
marketIndex,
|
|
1430
|
+
maxBaseAssetAmount,
|
|
1322
1431
|
{
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1432
|
+
accounts: {
|
|
1433
|
+
state: await this.getStatePublicKey(),
|
|
1434
|
+
authority: this.wallet.publicKey,
|
|
1435
|
+
user: userAccountPublicKey,
|
|
1436
|
+
liquidator: liquidatorPublicKey,
|
|
1437
|
+
},
|
|
1438
|
+
remainingAccounts: remainingAccounts,
|
|
1439
|
+
}
|
|
1440
|
+
);
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1443
|
+
public async liquidateBorrow(
|
|
1444
|
+
userAccountPublicKey: PublicKey,
|
|
1445
|
+
userAccount: UserAccount,
|
|
1446
|
+
assetBankIndex: BN,
|
|
1447
|
+
liabilityBankIndex: BN,
|
|
1448
|
+
maxLiabilityTransfer: BN
|
|
1449
|
+
): Promise<TransactionSignature> {
|
|
1450
|
+
const { txSig } = await this.txSender.send(
|
|
1451
|
+
wrapInTx(
|
|
1452
|
+
await this.getLiquidateBorrowIx(
|
|
1453
|
+
userAccountPublicKey,
|
|
1454
|
+
userAccount,
|
|
1455
|
+
assetBankIndex,
|
|
1456
|
+
liabilityBankIndex,
|
|
1457
|
+
maxLiabilityTransfer
|
|
1458
|
+
)
|
|
1459
|
+
),
|
|
1460
|
+
[],
|
|
1461
|
+
this.opts
|
|
1462
|
+
);
|
|
1463
|
+
return txSig;
|
|
1464
|
+
}
|
|
1465
|
+
|
|
1466
|
+
public async getLiquidateBorrowIx(
|
|
1467
|
+
userAccountPublicKey: PublicKey,
|
|
1468
|
+
userAccount: UserAccount,
|
|
1469
|
+
assetBankIndex: BN,
|
|
1470
|
+
liabilityBankIndex: BN,
|
|
1471
|
+
maxLiabilityTransfer: BN
|
|
1472
|
+
): Promise<TransactionInstruction> {
|
|
1473
|
+
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
1474
|
+
|
|
1475
|
+
const remainingAccounts = this.getRemainingAccountsForLiquidation({
|
|
1476
|
+
userAccount,
|
|
1477
|
+
writableBankIndexes: [liabilityBankIndex, assetBankIndex],
|
|
1478
|
+
});
|
|
1479
|
+
|
|
1480
|
+
return await this.program.instruction.liquidateBorrow(
|
|
1481
|
+
assetBankIndex,
|
|
1482
|
+
liabilityBankIndex,
|
|
1483
|
+
maxLiabilityTransfer,
|
|
1484
|
+
{
|
|
1485
|
+
accounts: {
|
|
1486
|
+
state: await this.getStatePublicKey(),
|
|
1487
|
+
authority: this.wallet.publicKey,
|
|
1488
|
+
user: userAccountPublicKey,
|
|
1489
|
+
liquidator: liquidatorPublicKey,
|
|
1490
|
+
},
|
|
1491
|
+
remainingAccounts: remainingAccounts,
|
|
1492
|
+
}
|
|
1493
|
+
);
|
|
1494
|
+
}
|
|
1495
|
+
|
|
1496
|
+
public async liquidateBorrowForPerpPnl(
|
|
1497
|
+
userAccountPublicKey: PublicKey,
|
|
1498
|
+
userAccount: UserAccount,
|
|
1499
|
+
perpMarketIndex: BN,
|
|
1500
|
+
liabilityBankIndex: BN,
|
|
1501
|
+
maxLiabilityTransfer: BN
|
|
1502
|
+
): Promise<TransactionSignature> {
|
|
1503
|
+
const { txSig } = await this.txSender.send(
|
|
1504
|
+
wrapInTx(
|
|
1505
|
+
await this.getLiquidateBorrowForPerpPnlIx(
|
|
1506
|
+
userAccountPublicKey,
|
|
1507
|
+
userAccount,
|
|
1508
|
+
perpMarketIndex,
|
|
1509
|
+
liabilityBankIndex,
|
|
1510
|
+
maxLiabilityTransfer
|
|
1511
|
+
)
|
|
1512
|
+
),
|
|
1513
|
+
[],
|
|
1514
|
+
this.opts
|
|
1515
|
+
);
|
|
1516
|
+
return txSig;
|
|
1517
|
+
}
|
|
1518
|
+
|
|
1519
|
+
public async getLiquidateBorrowForPerpPnlIx(
|
|
1520
|
+
userAccountPublicKey: PublicKey,
|
|
1521
|
+
userAccount: UserAccount,
|
|
1522
|
+
perpMarketIndex: BN,
|
|
1523
|
+
liabilityBankIndex: BN,
|
|
1524
|
+
maxLiabilityTransfer: BN
|
|
1525
|
+
): Promise<TransactionInstruction> {
|
|
1526
|
+
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
1527
|
+
|
|
1528
|
+
const remainingAccounts = this.getRemainingAccountsForLiquidation({
|
|
1529
|
+
userAccount,
|
|
1530
|
+
writableMarketIndex: perpMarketIndex,
|
|
1531
|
+
writableBankIndexes: [liabilityBankIndex],
|
|
1532
|
+
});
|
|
1533
|
+
|
|
1534
|
+
return await this.program.instruction.liquidateBorrowForPerpPnl(
|
|
1535
|
+
perpMarketIndex,
|
|
1536
|
+
liabilityBankIndex,
|
|
1537
|
+
maxLiabilityTransfer,
|
|
1538
|
+
{
|
|
1539
|
+
accounts: {
|
|
1540
|
+
state: await this.getStatePublicKey(),
|
|
1541
|
+
authority: this.wallet.publicKey,
|
|
1542
|
+
user: userAccountPublicKey,
|
|
1543
|
+
liquidator: liquidatorPublicKey,
|
|
1544
|
+
},
|
|
1545
|
+
remainingAccounts: remainingAccounts,
|
|
1546
|
+
}
|
|
1547
|
+
);
|
|
1548
|
+
}
|
|
1549
|
+
|
|
1550
|
+
public async liquidatePerpPnlForDeposit(
|
|
1551
|
+
userAccountPublicKey: PublicKey,
|
|
1552
|
+
userAccount: UserAccount,
|
|
1553
|
+
perpMarketIndex: BN,
|
|
1554
|
+
assetBankIndex: BN,
|
|
1555
|
+
maxPnlTransfer: BN
|
|
1556
|
+
): Promise<TransactionSignature> {
|
|
1557
|
+
const { txSig } = await this.txSender.send(
|
|
1558
|
+
wrapInTx(
|
|
1559
|
+
await this.getLiquidatePerpPnlForDepositIx(
|
|
1560
|
+
userAccountPublicKey,
|
|
1561
|
+
userAccount,
|
|
1562
|
+
perpMarketIndex,
|
|
1563
|
+
assetBankIndex,
|
|
1564
|
+
maxPnlTransfer
|
|
1565
|
+
)
|
|
1566
|
+
),
|
|
1567
|
+
[],
|
|
1568
|
+
this.opts
|
|
1569
|
+
);
|
|
1570
|
+
return txSig;
|
|
1571
|
+
}
|
|
1572
|
+
|
|
1573
|
+
public async getLiquidatePerpPnlForDepositIx(
|
|
1574
|
+
userAccountPublicKey: PublicKey,
|
|
1575
|
+
userAccount: UserAccount,
|
|
1576
|
+
perpMarketIndex: BN,
|
|
1577
|
+
assetBankIndex: BN,
|
|
1578
|
+
maxPnlTransfer: BN
|
|
1579
|
+
): Promise<TransactionInstruction> {
|
|
1580
|
+
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
1581
|
+
|
|
1582
|
+
const remainingAccounts = this.getRemainingAccountsForLiquidation({
|
|
1583
|
+
userAccount,
|
|
1584
|
+
writableMarketIndex: perpMarketIndex,
|
|
1585
|
+
writableBankIndexes: [assetBankIndex],
|
|
1586
|
+
});
|
|
1587
|
+
|
|
1588
|
+
return await this.program.instruction.liquidatePerpPnlForDeposit(
|
|
1589
|
+
perpMarketIndex,
|
|
1590
|
+
assetBankIndex,
|
|
1591
|
+
maxPnlTransfer,
|
|
1592
|
+
{
|
|
1593
|
+
accounts: {
|
|
1594
|
+
state: await this.getStatePublicKey(),
|
|
1595
|
+
authority: this.wallet.publicKey,
|
|
1596
|
+
user: userAccountPublicKey,
|
|
1597
|
+
liquidator: liquidatorPublicKey,
|
|
1598
|
+
},
|
|
1599
|
+
remainingAccounts: remainingAccounts,
|
|
1600
|
+
}
|
|
1601
|
+
);
|
|
1602
|
+
}
|
|
1603
|
+
|
|
1604
|
+
getRemainingAccountsForLiquidation(params: {
|
|
1605
|
+
userAccount: UserAccount;
|
|
1606
|
+
writableMarketIndex?: BN;
|
|
1607
|
+
writableBankIndexes?: BN[];
|
|
1608
|
+
}): AccountMeta[] {
|
|
1609
|
+
const liquidateeUserAccount = params.userAccount;
|
|
1610
|
+
|
|
1611
|
+
const oracleAccountMap = new Map<string, AccountMeta>();
|
|
1612
|
+
const bankAccountMap = new Map<number, AccountMeta>();
|
|
1613
|
+
const marketAccountMap = new Map<number, AccountMeta>();
|
|
1614
|
+
for (const bankBalance of liquidateeUserAccount.bankBalances) {
|
|
1615
|
+
if (!bankBalance.balance.eq(ZERO)) {
|
|
1616
|
+
const bankAccount = this.getBankAccount(bankBalance.bankIndex);
|
|
1617
|
+
bankAccountMap.set(bankBalance.bankIndex.toNumber(), {
|
|
1618
|
+
pubkey: bankAccount.pubkey,
|
|
1619
|
+
isSigner: false,
|
|
1620
|
+
isWritable: false,
|
|
1621
|
+
});
|
|
1622
|
+
|
|
1623
|
+
if (!bankAccount.oracle.equals(PublicKey.default)) {
|
|
1624
|
+
oracleAccountMap.set(bankAccount.oracle.toString(), {
|
|
1625
|
+
pubkey: bankAccount.oracle,
|
|
1626
|
+
isSigner: false,
|
|
1627
|
+
isWritable: false,
|
|
1628
|
+
});
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1631
|
+
}
|
|
1330
1632
|
for (const position of liquidateeUserAccount.positions) {
|
|
1331
1633
|
if (!positionIsAvailable(position)) {
|
|
1332
1634
|
const market = this.getMarketAccount(position.marketIndex);
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
);
|
|
1337
|
-
marketAccountInfos.push({
|
|
1338
|
-
pubkey: marketPublicKey,
|
|
1339
|
-
isWritable: true,
|
|
1635
|
+
marketAccountMap.set(position.marketIndex.toNumber(), {
|
|
1636
|
+
pubkey: market.pubkey,
|
|
1637
|
+
isWritable: false,
|
|
1340
1638
|
isSigner: false,
|
|
1341
1639
|
});
|
|
1342
|
-
|
|
1640
|
+
oracleAccountMap.set(market.amm.oracle.toString(), {
|
|
1343
1641
|
pubkey: market.amm.oracle,
|
|
1344
1642
|
isWritable: false,
|
|
1345
1643
|
isSigner: false,
|
|
1346
1644
|
});
|
|
1347
1645
|
}
|
|
1348
1646
|
}
|
|
1349
|
-
const remainingAccounts = oracleAccountInfos.concat(
|
|
1350
|
-
bankAccountInfos.concat(marketAccountInfos)
|
|
1351
|
-
);
|
|
1352
1647
|
|
|
1353
|
-
const
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1648
|
+
const userAccountAndSlot = this.getUserAccountAndSlot();
|
|
1649
|
+
if (!userAccountAndSlot) {
|
|
1650
|
+
throw Error(
|
|
1651
|
+
'No user account found. Most likely user account does not exist or failed to fetch account'
|
|
1652
|
+
);
|
|
1653
|
+
}
|
|
1654
|
+
const { data: userAccount, slot: lastUserPositionsSlot } =
|
|
1655
|
+
userAccountAndSlot;
|
|
1656
|
+
|
|
1657
|
+
for (const [marketIndexNum, slot] of this.marketLastSlotCache.entries()) {
|
|
1658
|
+
// if cache has more recent slot than user positions account slot, add market to remaining accounts
|
|
1659
|
+
// otherwise remove from slot
|
|
1660
|
+
if (slot > lastUserPositionsSlot) {
|
|
1661
|
+
const marketAccount = this.getMarketAccount(marketIndexNum);
|
|
1662
|
+
marketAccountMap.set(marketIndexNum, {
|
|
1663
|
+
pubkey: marketAccount.pubkey,
|
|
1664
|
+
isSigner: false,
|
|
1665
|
+
isWritable: false,
|
|
1666
|
+
});
|
|
1667
|
+
oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
|
|
1668
|
+
pubkey: marketAccount.amm.oracle,
|
|
1669
|
+
isSigner: false,
|
|
1670
|
+
isWritable: false,
|
|
1671
|
+
});
|
|
1672
|
+
} else {
|
|
1673
|
+
this.marketLastSlotCache.delete(marketIndexNum);
|
|
1674
|
+
}
|
|
1675
|
+
}
|
|
1676
|
+
for (const bankBalance of userAccount.bankBalances) {
|
|
1677
|
+
if (!bankBalance.balance.eq(ZERO)) {
|
|
1678
|
+
const bankAccount = this.getBankAccount(bankBalance.bankIndex);
|
|
1679
|
+
bankAccountMap.set(bankBalance.bankIndex.toNumber(), {
|
|
1680
|
+
pubkey: bankAccount.pubkey,
|
|
1681
|
+
isSigner: false,
|
|
1682
|
+
isWritable: false,
|
|
1683
|
+
});
|
|
1684
|
+
|
|
1685
|
+
if (!bankAccount.oracle.equals(PublicKey.default)) {
|
|
1686
|
+
oracleAccountMap.set(bankAccount.oracle.toString(), {
|
|
1687
|
+
pubkey: bankAccount.oracle,
|
|
1688
|
+
isSigner: false,
|
|
1689
|
+
isWritable: false,
|
|
1690
|
+
});
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1693
|
+
}
|
|
1694
|
+
for (const position of userAccount.positions) {
|
|
1695
|
+
if (!positionIsAvailable(position)) {
|
|
1696
|
+
const market = this.getMarketAccount(position.marketIndex);
|
|
1697
|
+
marketAccountMap.set(position.marketIndex.toNumber(), {
|
|
1698
|
+
pubkey: market.pubkey,
|
|
1699
|
+
isWritable: false,
|
|
1700
|
+
isSigner: false,
|
|
1701
|
+
});
|
|
1702
|
+
oracleAccountMap.set(market.amm.oracle.toString(), {
|
|
1703
|
+
pubkey: market.amm.oracle,
|
|
1704
|
+
isWritable: false,
|
|
1705
|
+
isSigner: false,
|
|
1706
|
+
});
|
|
1707
|
+
}
|
|
1708
|
+
}
|
|
1709
|
+
|
|
1710
|
+
if (params.writableMarketIndex) {
|
|
1711
|
+
const market = this.getMarketAccount(params.writableMarketIndex);
|
|
1712
|
+
marketAccountMap.set(market.marketIndex.toNumber(), {
|
|
1713
|
+
pubkey: market.pubkey,
|
|
1714
|
+
isSigner: false,
|
|
1715
|
+
isWritable: true,
|
|
1716
|
+
});
|
|
1717
|
+
oracleAccountMap.set(market.amm.oracle.toString(), {
|
|
1718
|
+
pubkey: market.amm.oracle,
|
|
1719
|
+
isSigner: false,
|
|
1720
|
+
isWritable: false,
|
|
1721
|
+
});
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1724
|
+
if (params.writableBankIndexes) {
|
|
1725
|
+
for (const writableBankIndex of params.writableBankIndexes) {
|
|
1726
|
+
const bank = this.getBankAccount(writableBankIndex);
|
|
1727
|
+
bankAccountMap.set(bank.bankIndex.toNumber(), {
|
|
1728
|
+
pubkey: bank.pubkey,
|
|
1729
|
+
isSigner: false,
|
|
1730
|
+
isWritable: true,
|
|
1731
|
+
});
|
|
1732
|
+
if (!bank.oracle.equals(PublicKey.default)) {
|
|
1733
|
+
oracleAccountMap.set(bank.oracle.toString(), {
|
|
1734
|
+
pubkey: bank.oracle,
|
|
1735
|
+
isSigner: false,
|
|
1736
|
+
isWritable: false,
|
|
1737
|
+
});
|
|
1738
|
+
}
|
|
1739
|
+
}
|
|
1740
|
+
}
|
|
1741
|
+
|
|
1742
|
+
return [
|
|
1743
|
+
...oracleAccountMap.values(),
|
|
1744
|
+
...bankAccountMap.values(),
|
|
1745
|
+
...marketAccountMap.values(),
|
|
1746
|
+
];
|
|
1368
1747
|
}
|
|
1369
1748
|
|
|
1370
1749
|
public async updateFundingRate(
|