@drift-labs/sdk 2.43.0-beta.1 → 2.43.0-beta.11
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/README.md +1 -0
- package/VERSION +1 -1
- package/bun.lockb +0 -0
- package/get_events.ts +47 -0
- package/lib/constants/perpMarkets.js +20 -0
- package/lib/dlob/DLOB.js +3 -1
- package/lib/dlob/orderBookLevels.d.ts +2 -0
- package/lib/dlob/orderBookLevels.js +9 -1
- package/lib/driftClient.js +51 -49
- package/lib/user.js +4 -1
- package/package.json +2 -1
- package/src/constants/perpMarkets.ts +20 -0
- package/src/dlob/DLOB.ts +3 -1
- package/src/dlob/orderBookLevels.ts +13 -1
- package/src/driftClient.ts +64 -59
- package/src/user.ts +5 -1
- package/tests/amm/test.ts +78 -0
- package/tests/user/test.ts +10 -13
package/README.md
CHANGED
|
@@ -244,3 +244,4 @@ Drift Protocol v2 is licensed under [Apache 2.0](./LICENSE).
|
|
|
244
244
|
Unless you explicitly state otherwise, any contribution intentionally submitted
|
|
245
245
|
for inclusion in Drift SDK by you, as defined in the Apache-2.0 license, shall be
|
|
246
246
|
licensed as above, without any additional terms or conditions.
|
|
247
|
+
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.43.0-beta.
|
|
1
|
+
2.43.0-beta.11
|
package/bun.lockb
CHANGED
|
Binary file
|
package/get_events.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Connection, Keypair, PublicKey } from '@solana/web3.js';
|
|
2
|
+
import {
|
|
3
|
+
configs,
|
|
4
|
+
DriftClient,
|
|
5
|
+
Wallet,
|
|
6
|
+
} from "@drift-labs/sdk";
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
async function main() {
|
|
10
|
+
|
|
11
|
+
const driftConfig = configs['mainnet-beta'];
|
|
12
|
+
const connection = new Connection('https://api.mainnet-beta.solana.com');
|
|
13
|
+
|
|
14
|
+
const driftClient = new DriftClient({
|
|
15
|
+
connection: connection,
|
|
16
|
+
wallet: new Wallet(new Keypair()),
|
|
17
|
+
programID: new PublicKey(driftConfig.DRIFT_PROGRAM_ID),
|
|
18
|
+
userStats: true,
|
|
19
|
+
env: 'mainnet-beta',
|
|
20
|
+
});
|
|
21
|
+
console.log(`driftClientSubscribed: ${await driftClient.subscribe()}`);
|
|
22
|
+
|
|
23
|
+
const txHash = "3gvGQufckXGHrFDv4dNWEXuXKRMy3NZkKHMyFrAhLoYScaXXTGCp9vq58kWkfyJ8oDYZrz4bTyGayjUy9PKigeLS";
|
|
24
|
+
|
|
25
|
+
const tx = await driftClient.connection.getParsedTransaction(txHash, {
|
|
26
|
+
commitment: "confirmed",
|
|
27
|
+
maxSupportedTransactionVersion: 0,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
let logIdx = 0;
|
|
31
|
+
// @ts-ignore
|
|
32
|
+
for (const event of driftClient.program._events._eventParser.parseLogs(tx!.meta!.logMessages)) {
|
|
33
|
+
console.log("----------------------------------------");
|
|
34
|
+
console.log(`Log ${logIdx++}`);
|
|
35
|
+
console.log("----------------------------------------");
|
|
36
|
+
console.log(`${JSON.stringify(event, null, 2)}`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
console.log("========================================");
|
|
40
|
+
console.log("Raw transaction logs");
|
|
41
|
+
console.log("========================================");
|
|
42
|
+
console.log(JSON.stringify(tx!.meta!.logMessages, null, 2));
|
|
43
|
+
|
|
44
|
+
process.exit(0);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
main().catch(console.error);
|
|
@@ -174,6 +174,16 @@ exports.DevnetPerpMarkets = [
|
|
|
174
174
|
launchTs: 1698074659000,
|
|
175
175
|
oracleSource: __1.OracleSource.PYTH,
|
|
176
176
|
},
|
|
177
|
+
{
|
|
178
|
+
fullName: 'Rollbit',
|
|
179
|
+
category: ['Exchange'],
|
|
180
|
+
symbol: 'RLB-PERP',
|
|
181
|
+
baseAssetSymbol: 'RLB',
|
|
182
|
+
marketIndex: 17,
|
|
183
|
+
oracle: new web3_js_1.PublicKey('6BmJozusMugAySsfNfMFsU1YRWcGwyP3oycNX9Pv9oCz'),
|
|
184
|
+
launchTs: 11699265968000,
|
|
185
|
+
oracleSource: __1.OracleSource.PYTH,
|
|
186
|
+
},
|
|
177
187
|
];
|
|
178
188
|
exports.MainnetPerpMarkets = [
|
|
179
189
|
{
|
|
@@ -346,6 +356,16 @@ exports.MainnetPerpMarkets = [
|
|
|
346
356
|
launchTs: 1698074659000,
|
|
347
357
|
oracleSource: __1.OracleSource.PYTH,
|
|
348
358
|
},
|
|
359
|
+
{
|
|
360
|
+
fullName: 'Rollbit',
|
|
361
|
+
category: ['Exchange'],
|
|
362
|
+
symbol: 'RLB-PERP',
|
|
363
|
+
baseAssetSymbol: 'RLB',
|
|
364
|
+
marketIndex: 17,
|
|
365
|
+
oracle: new web3_js_1.PublicKey('4BA3RcS4zE32WWgp49vvvre2t6nXY1W1kMyKZxeeuUey'),
|
|
366
|
+
launchTs: 11699265968000,
|
|
367
|
+
oracleSource: __1.OracleSource.PYTH,
|
|
368
|
+
},
|
|
349
369
|
];
|
|
350
370
|
exports.PerpMarkets = {
|
|
351
371
|
devnet: exports.DevnetPerpMarkets,
|
package/lib/dlob/DLOB.js
CHANGED
|
@@ -600,7 +600,7 @@ class DLOB {
|
|
|
600
600
|
bestGenerator.next = bestGenerator.generator.next();
|
|
601
601
|
continue;
|
|
602
602
|
}
|
|
603
|
-
if (filterFcn && filterFcn(bestGenerator.next.value)) {
|
|
603
|
+
if (filterFcn && !filterFcn(bestGenerator.next.value)) {
|
|
604
604
|
bestGenerator.next = bestGenerator.generator.next();
|
|
605
605
|
continue;
|
|
606
606
|
}
|
|
@@ -956,6 +956,7 @@ class DLOB {
|
|
|
956
956
|
return {
|
|
957
957
|
bids,
|
|
958
958
|
asks,
|
|
959
|
+
slot,
|
|
959
960
|
};
|
|
960
961
|
}
|
|
961
962
|
/**
|
|
@@ -990,6 +991,7 @@ class DLOB {
|
|
|
990
991
|
return {
|
|
991
992
|
bids,
|
|
992
993
|
asks,
|
|
994
|
+
slot,
|
|
993
995
|
};
|
|
994
996
|
}
|
|
995
997
|
estimateFillExactBaseAmountInForSide(baseAmountIn, oraclePriceData, slot, dlobSide) {
|
|
@@ -12,6 +12,7 @@ export type L2Level = {
|
|
|
12
12
|
export type L2OrderBook = {
|
|
13
13
|
asks: L2Level[];
|
|
14
14
|
bids: L2Level[];
|
|
15
|
+
slot?: number;
|
|
15
16
|
};
|
|
16
17
|
export interface L2OrderBookGenerator {
|
|
17
18
|
getL2Asks(): Generator<L2Level>;
|
|
@@ -26,6 +27,7 @@ export type L3Level = {
|
|
|
26
27
|
export type L3OrderBook = {
|
|
27
28
|
asks: L3Level[];
|
|
28
29
|
bids: L3Level[];
|
|
30
|
+
slot?: number;
|
|
29
31
|
};
|
|
30
32
|
export declare const DEFAULT_TOP_OF_BOOK_QUOTE_AMOUNTS: BN[];
|
|
31
33
|
/**
|
|
@@ -92,7 +92,14 @@ function getVammL2Generator({ marketAccount, oraclePriceData, numOrders, now, to
|
|
|
92
92
|
(0, assert_1.assert)(topOfBookQuoteAmounts.length < numOrders);
|
|
93
93
|
}
|
|
94
94
|
const updatedAmm = (0, __1.calculateUpdatedAMM)(marketAccount.amm, oraclePriceData);
|
|
95
|
-
|
|
95
|
+
let [openBids, openAsks] = (0, __1.calculateMarketOpenBidAsk)(updatedAmm.baseAssetReserve, updatedAmm.minBaseAssetReserve, updatedAmm.maxBaseAssetReserve, updatedAmm.orderStepSize);
|
|
96
|
+
const minOrderSize = marketAccount.amm.orderStepSize;
|
|
97
|
+
if (openBids.lt(minOrderSize.muln(2))) {
|
|
98
|
+
openBids = __1.ZERO;
|
|
99
|
+
}
|
|
100
|
+
if (openAsks.abs().lt(minOrderSize.muln(2))) {
|
|
101
|
+
openAsks = __1.ZERO;
|
|
102
|
+
}
|
|
96
103
|
now = now !== null && now !== void 0 ? now : new __1.BN(Date.now() / 1000);
|
|
97
104
|
const [bidReserves, askReserves] = (0, __1.calculateSpreadReserves)(updatedAmm, oraclePriceData, now);
|
|
98
105
|
let numBids = 0;
|
|
@@ -202,6 +209,7 @@ function groupL2(l2, grouping, depth) {
|
|
|
202
209
|
return {
|
|
203
210
|
bids: groupL2Levels(l2.bids, grouping, __1.PositionDirection.LONG, depth),
|
|
204
211
|
asks: groupL2Levels(l2.asks, grouping, __1.PositionDirection.SHORT, depth),
|
|
212
|
+
slot: l2.slot,
|
|
205
213
|
};
|
|
206
214
|
}
|
|
207
215
|
exports.groupL2 = groupL2;
|
package/lib/driftClient.js
CHANGED
|
@@ -418,14 +418,15 @@ class DriftClient {
|
|
|
418
418
|
return result;
|
|
419
419
|
}
|
|
420
420
|
async initializeUserAccount(subAccountId = 0, name = userName_1.DEFAULT_USER_NAME, referrerInfo) {
|
|
421
|
+
const initializeIxs = [];
|
|
421
422
|
const [userAccountPublicKey, initializeUserAccountIx] = await this.getInitializeUserInstructions(subAccountId, name, referrerInfo);
|
|
422
|
-
const tx = new web3_js_1.Transaction();
|
|
423
423
|
if (subAccountId === 0) {
|
|
424
424
|
if (!(await this.checkIfAccountExists(this.getUserStatsAccountPublicKey()))) {
|
|
425
|
-
|
|
425
|
+
initializeIxs.push(await this.getInitializeUserStatsIx());
|
|
426
426
|
}
|
|
427
427
|
}
|
|
428
|
-
|
|
428
|
+
initializeIxs.push(initializeUserAccountIx);
|
|
429
|
+
const tx = await this.buildTransaction(initializeIxs);
|
|
429
430
|
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
430
431
|
await this.addUser(subAccountId);
|
|
431
432
|
return [txSig, userAccountPublicKey];
|
|
@@ -1052,18 +1053,19 @@ class DriftClient {
|
|
|
1052
1053
|
*/
|
|
1053
1054
|
async initializeUserAccountAndDepositCollateral(amount, userTokenAccount, marketIndex = 0, subAccountId = 0, name = userName_1.DEFAULT_USER_NAME, fromSubAccountId, referrerInfo, txParams) {
|
|
1054
1055
|
var _a;
|
|
1056
|
+
const ixs = [];
|
|
1055
1057
|
const [userAccountPublicKey, initializeUserAccountIx] = await this.getInitializeUserInstructions(subAccountId, name, referrerInfo);
|
|
1056
1058
|
const additionalSigners = [];
|
|
1057
1059
|
const spotMarket = this.getSpotMarketAccount(marketIndex);
|
|
1058
1060
|
const isSolMarket = spotMarket.mint.equals(spotMarkets_1.WRAPPED_SOL_MINT);
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
}));
|
|
1061
|
+
let params = {
|
|
1062
|
+
computeUnits: (_a = txParams === null || txParams === void 0 ? void 0 : txParams.computeUnits) !== null && _a !== void 0 ? _a : 600000,
|
|
1063
|
+
};
|
|
1063
1064
|
if (txParams === null || txParams === void 0 ? void 0 : txParams.computeUnitsPrice) {
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1065
|
+
params = {
|
|
1066
|
+
...params,
|
|
1067
|
+
computeUnitsPrice: txParams.computeUnitsPrice,
|
|
1068
|
+
};
|
|
1067
1069
|
}
|
|
1068
1070
|
const authority = this.wallet.publicKey;
|
|
1069
1071
|
const isFromSubaccount = fromSubAccountId !== null &&
|
|
@@ -1073,40 +1075,41 @@ class DriftClient {
|
|
|
1073
1075
|
if (createWSOLTokenAccount) {
|
|
1074
1076
|
const { ixs: startIxs, pubkey } = await this.getWrappedSolAccountCreationIxs(amount, true);
|
|
1075
1077
|
userTokenAccount = pubkey;
|
|
1076
|
-
|
|
1077
|
-
tx.add(ix);
|
|
1078
|
-
});
|
|
1078
|
+
ixs.push(...startIxs);
|
|
1079
1079
|
}
|
|
1080
1080
|
const depositCollateralIx = isFromSubaccount
|
|
1081
1081
|
? await this.getTransferDepositIx(amount, marketIndex, fromSubAccountId, subAccountId)
|
|
1082
1082
|
: await this.getDepositInstruction(amount, marketIndex, userTokenAccount, subAccountId, false, false);
|
|
1083
1083
|
if (subAccountId === 0) {
|
|
1084
1084
|
if (!(await this.checkIfAccountExists(this.getUserStatsAccountPublicKey()))) {
|
|
1085
|
-
|
|
1085
|
+
ixs.push(await this.getInitializeUserStatsIx());
|
|
1086
1086
|
}
|
|
1087
1087
|
}
|
|
1088
|
-
|
|
1088
|
+
ixs.push(initializeUserAccountIx, depositCollateralIx);
|
|
1089
1089
|
// Close the wrapped sol account at the end of the transaction
|
|
1090
1090
|
if (createWSOLTokenAccount) {
|
|
1091
|
-
|
|
1091
|
+
ixs.push((0, spl_token_1.createCloseAccountInstruction)(userTokenAccount, authority, authority, []));
|
|
1092
1092
|
}
|
|
1093
|
+
const tx = await this.buildTransaction(ixs, params);
|
|
1093
1094
|
const { txSig, slot } = await this.sendTransaction(tx, additionalSigners, this.opts);
|
|
1094
1095
|
this.spotMarketLastSlotCache.set(marketIndex, slot);
|
|
1095
1096
|
await this.addUser(subAccountId);
|
|
1096
1097
|
return [txSig, userAccountPublicKey];
|
|
1097
1098
|
}
|
|
1098
1099
|
async initializeUserAccountForDevnet(subAccountId = 0, name = userName_1.DEFAULT_USER_NAME, marketIndex, tokenFaucet, amount, referrerInfo) {
|
|
1100
|
+
const ixs = [];
|
|
1099
1101
|
const [associateTokenPublicKey, createAssociatedAccountIx, mintToIx] = await tokenFaucet.createAssociatedTokenAccountAndMintToInstructions(this.wallet.publicKey, amount);
|
|
1100
1102
|
const [userAccountPublicKey, initializeUserAccountIx] = await this.getInitializeUserInstructions(subAccountId, name, referrerInfo);
|
|
1101
1103
|
const depositCollateralIx = await this.getDepositInstruction(amount, marketIndex, associateTokenPublicKey, subAccountId, false, false);
|
|
1102
|
-
|
|
1104
|
+
ixs.push(createAssociatedAccountIx, mintToIx);
|
|
1103
1105
|
if (subAccountId === 0) {
|
|
1104
1106
|
if (!(await this.checkIfAccountExists(this.getUserStatsAccountPublicKey()))) {
|
|
1105
|
-
|
|
1107
|
+
ixs.push(await this.getInitializeUserStatsIx());
|
|
1106
1108
|
}
|
|
1107
1109
|
}
|
|
1108
|
-
|
|
1109
|
-
const
|
|
1110
|
+
ixs.push(initializeUserAccountIx, depositCollateralIx);
|
|
1111
|
+
const tx = await this.buildTransaction(ixs);
|
|
1112
|
+
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
1110
1113
|
await this.addUser(subAccountId);
|
|
1111
1114
|
return [txSig, userAccountPublicKey];
|
|
1112
1115
|
}
|
|
@@ -1118,10 +1121,7 @@ class DriftClient {
|
|
|
1118
1121
|
* @param reduceOnly
|
|
1119
1122
|
*/
|
|
1120
1123
|
async withdraw(amount, marketIndex, associatedTokenAddress, reduceOnly = false) {
|
|
1121
|
-
const
|
|
1122
|
-
tx.add(web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
|
|
1123
|
-
units: 600000,
|
|
1124
|
-
}));
|
|
1124
|
+
const withdrawIxs = [];
|
|
1125
1125
|
const additionalSigners = [];
|
|
1126
1126
|
const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
|
|
1127
1127
|
const isSolMarket = spotMarketAccount.mint.equals(spotMarkets_1.WRAPPED_SOL_MINT);
|
|
@@ -1130,23 +1130,24 @@ class DriftClient {
|
|
|
1130
1130
|
if (createWSOLTokenAccount) {
|
|
1131
1131
|
const { ixs, pubkey } = await this.getWrappedSolAccountCreationIxs(amount, false);
|
|
1132
1132
|
associatedTokenAddress = pubkey;
|
|
1133
|
-
|
|
1134
|
-
tx.add(ix);
|
|
1135
|
-
});
|
|
1133
|
+
withdrawIxs.push(...ixs);
|
|
1136
1134
|
}
|
|
1137
1135
|
else {
|
|
1138
1136
|
const accountExists = await this.checkIfAccountExists(associatedTokenAddress);
|
|
1139
1137
|
if (!accountExists) {
|
|
1140
1138
|
const createAssociatedTokenAccountIx = this.getAssociatedTokenAccountCreationIx(spotMarketAccount.mint, associatedTokenAddress);
|
|
1141
|
-
|
|
1139
|
+
withdrawIxs.push(createAssociatedTokenAccountIx);
|
|
1142
1140
|
}
|
|
1143
1141
|
}
|
|
1144
|
-
const
|
|
1145
|
-
|
|
1142
|
+
const withdrawCollateralIx = await this.getWithdrawIx(amount, spotMarketAccount.marketIndex, associatedTokenAddress, reduceOnly);
|
|
1143
|
+
withdrawIxs.push(withdrawCollateralIx);
|
|
1146
1144
|
// Close the wrapped sol account at the end of the transaction
|
|
1147
1145
|
if (createWSOLTokenAccount) {
|
|
1148
|
-
|
|
1146
|
+
withdrawIxs.push((0, spl_token_1.createCloseAccountInstruction)(associatedTokenAddress, authority, authority, []));
|
|
1149
1147
|
}
|
|
1148
|
+
const tx = await this.buildTransaction(withdrawIxs, {
|
|
1149
|
+
computeUnits: 600000,
|
|
1150
|
+
});
|
|
1150
1151
|
const { txSig, slot } = await this.sendTransaction(tx, additionalSigners, this.opts);
|
|
1151
1152
|
this.spotMarketLastSlotCache.set(marketIndex, slot);
|
|
1152
1153
|
return txSig;
|
|
@@ -2698,11 +2699,7 @@ class DriftClient {
|
|
|
2698
2699
|
}
|
|
2699
2700
|
async settlePNLs(users, marketIndexes) {
|
|
2700
2701
|
const ixs = await this.getSettlePNLsIxs(users, marketIndexes);
|
|
2701
|
-
const tx =
|
|
2702
|
-
.add(web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
|
|
2703
|
-
units: 1000000,
|
|
2704
|
-
}))
|
|
2705
|
-
.add(...ixs);
|
|
2702
|
+
const tx = await this.buildTransaction(ixs, { computeUnits: 1000000 });
|
|
2706
2703
|
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
2707
2704
|
return txSig;
|
|
2708
2705
|
}
|
|
@@ -3030,7 +3027,7 @@ class DriftClient {
|
|
|
3030
3027
|
* Add to an insurance fund stake and optionally initialize the account
|
|
3031
3028
|
*/
|
|
3032
3029
|
async addInsuranceFundStake({ marketIndex, amount, collateralAccountPublicKey, initializeStakeAccount, fromSubaccount, }) {
|
|
3033
|
-
const
|
|
3030
|
+
const addIfStakeIxs = [];
|
|
3034
3031
|
const additionalSigners = [];
|
|
3035
3032
|
const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
|
|
3036
3033
|
const isSolMarket = spotMarketAccount.mint.equals(spotMarkets_1.WRAPPED_SOL_MINT);
|
|
@@ -3040,7 +3037,7 @@ class DriftClient {
|
|
|
3040
3037
|
const { ixs, pubkey } = await this.getWrappedSolAccountCreationIxs(amount, true);
|
|
3041
3038
|
tokenAccount = pubkey;
|
|
3042
3039
|
ixs.forEach((ix) => {
|
|
3043
|
-
|
|
3040
|
+
addIfStakeIxs.push(ix);
|
|
3044
3041
|
});
|
|
3045
3042
|
}
|
|
3046
3043
|
else {
|
|
@@ -3048,17 +3045,18 @@ class DriftClient {
|
|
|
3048
3045
|
}
|
|
3049
3046
|
if (fromSubaccount) {
|
|
3050
3047
|
const withdrawIx = await this.getWithdrawIx(amount, marketIndex, tokenAccount);
|
|
3051
|
-
|
|
3048
|
+
addIfStakeIxs.push(withdrawIx);
|
|
3052
3049
|
}
|
|
3053
3050
|
if (initializeStakeAccount) {
|
|
3054
3051
|
const initializeIx = await this.getInitializeInsuranceFundStakeIx(marketIndex);
|
|
3055
|
-
|
|
3052
|
+
addIfStakeIxs.push(initializeIx);
|
|
3056
3053
|
}
|
|
3057
3054
|
const addFundsIx = await this.getAddInsuranceFundStakeIx(marketIndex, amount, tokenAccount);
|
|
3058
|
-
|
|
3055
|
+
addIfStakeIxs.push(addFundsIx);
|
|
3059
3056
|
if (createWSOLTokenAccount) {
|
|
3060
|
-
|
|
3057
|
+
addIfStakeIxs.push((0, spl_token_1.createCloseAccountInstruction)(tokenAccount, this.wallet.publicKey, this.wallet.publicKey, []));
|
|
3061
3058
|
}
|
|
3059
|
+
const tx = await this.buildTransaction(addIfStakeIxs);
|
|
3062
3060
|
const { txSig } = await this.sendTransaction(tx, additionalSigners, this.opts);
|
|
3063
3061
|
return txSig;
|
|
3064
3062
|
}
|
|
@@ -3070,7 +3068,7 @@ class DriftClient {
|
|
|
3070
3068
|
useMarketLastSlotCache: true,
|
|
3071
3069
|
writableSpotMarketIndexes: [marketIndex],
|
|
3072
3070
|
});
|
|
3073
|
-
const
|
|
3071
|
+
const ix = await this.program.instruction.requestRemoveInsuranceFundStake(marketIndex, amount, {
|
|
3074
3072
|
accounts: {
|
|
3075
3073
|
state: await this.getStatePublicKey(),
|
|
3076
3074
|
spotMarket: spotMarketAccount.pubkey,
|
|
@@ -3081,6 +3079,7 @@ class DriftClient {
|
|
|
3081
3079
|
},
|
|
3082
3080
|
remainingAccounts,
|
|
3083
3081
|
});
|
|
3082
|
+
const tx = await this.buildTransaction(ix);
|
|
3084
3083
|
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
3085
3084
|
return txSig;
|
|
3086
3085
|
}
|
|
@@ -3092,7 +3091,7 @@ class DriftClient {
|
|
|
3092
3091
|
useMarketLastSlotCache: true,
|
|
3093
3092
|
writableSpotMarketIndexes: [marketIndex],
|
|
3094
3093
|
});
|
|
3095
|
-
const
|
|
3094
|
+
const ix = await this.program.instruction.cancelRequestRemoveInsuranceFundStake(marketIndex, {
|
|
3096
3095
|
accounts: {
|
|
3097
3096
|
state: await this.getStatePublicKey(),
|
|
3098
3097
|
spotMarket: spotMarketAccount.pubkey,
|
|
@@ -3103,11 +3102,12 @@ class DriftClient {
|
|
|
3103
3102
|
},
|
|
3104
3103
|
remainingAccounts,
|
|
3105
3104
|
});
|
|
3105
|
+
const tx = await this.buildTransaction(ix);
|
|
3106
3106
|
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
3107
3107
|
return txSig;
|
|
3108
3108
|
}
|
|
3109
3109
|
async removeInsuranceFundStake(marketIndex, collateralAccountPublicKey) {
|
|
3110
|
-
const
|
|
3110
|
+
const removeIfStakeIxs = [];
|
|
3111
3111
|
const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
|
|
3112
3112
|
const ifStakeAccountPublicKey = (0, pda_1.getInsuranceFundStakeAccountPublicKey)(this.program.programId, this.wallet.publicKey, marketIndex);
|
|
3113
3113
|
const additionalSigners = [];
|
|
@@ -3118,7 +3118,7 @@ class DriftClient {
|
|
|
3118
3118
|
const { ixs, pubkey } = await this.getWrappedSolAccountCreationIxs(numericConstants_1.ZERO, true);
|
|
3119
3119
|
tokenAccount = pubkey;
|
|
3120
3120
|
ixs.forEach((ix) => {
|
|
3121
|
-
|
|
3121
|
+
removeIfStakeIxs.push(ix);
|
|
3122
3122
|
});
|
|
3123
3123
|
}
|
|
3124
3124
|
else {
|
|
@@ -3143,11 +3143,12 @@ class DriftClient {
|
|
|
3143
3143
|
},
|
|
3144
3144
|
remainingAccounts,
|
|
3145
3145
|
});
|
|
3146
|
-
|
|
3146
|
+
removeIfStakeIxs.push(removeStakeIx);
|
|
3147
3147
|
// Close the wrapped sol account at the end of the transaction
|
|
3148
3148
|
if (createWSOLTokenAccount) {
|
|
3149
|
-
|
|
3149
|
+
removeIfStakeIxs.push((0, spl_token_1.createCloseAccountInstruction)(tokenAccount, this.wallet.publicKey, this.wallet.publicKey, []));
|
|
3150
3150
|
}
|
|
3151
|
+
const tx = await this.buildTransaction(removeIfStakeIxs);
|
|
3151
3152
|
const { txSig } = await this.sendTransaction(tx, additionalSigners, this.opts);
|
|
3152
3153
|
return txSig;
|
|
3153
3154
|
}
|
|
@@ -3158,7 +3159,7 @@ class DriftClient {
|
|
|
3158
3159
|
useMarketLastSlotCache: true,
|
|
3159
3160
|
writableSpotMarketIndexes: [marketIndex],
|
|
3160
3161
|
});
|
|
3161
|
-
const
|
|
3162
|
+
const ix = await this.program.instruction.settleRevenueToInsuranceFund(marketIndex, {
|
|
3162
3163
|
accounts: {
|
|
3163
3164
|
state: await this.getStatePublicKey(),
|
|
3164
3165
|
spotMarket: spotMarketAccount.pubkey,
|
|
@@ -3169,6 +3170,7 @@ class DriftClient {
|
|
|
3169
3170
|
},
|
|
3170
3171
|
remainingAccounts,
|
|
3171
3172
|
});
|
|
3173
|
+
const tx = await this.buildTransaction(ix);
|
|
3172
3174
|
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
3173
3175
|
return txSig;
|
|
3174
3176
|
}
|
package/lib/user.js
CHANGED
|
@@ -1564,7 +1564,10 @@ class User {
|
|
|
1564
1564
|
this.getEmptyPosition(targetMarketIndex);
|
|
1565
1565
|
const oracleData = this.getOracleDataForPerpMarket(targetMarketIndex);
|
|
1566
1566
|
let currentPositionQuoteAmount = this.getPerpPositionValue(targetMarketIndex, oracleData, includeOpenOrders);
|
|
1567
|
-
const
|
|
1567
|
+
const worstCaseBase = (0, margin_1.calculateWorstCaseBaseAssetAmount)(currentPosition);
|
|
1568
|
+
// current side is short if position base asset amount is negative OR there is no position open but open orders are short
|
|
1569
|
+
const currentSide = currentPosition.baseAssetAmount.isNeg() ||
|
|
1570
|
+
(currentPosition.baseAssetAmount.eq(numericConstants_1.ZERO) && worstCaseBase.isNeg())
|
|
1568
1571
|
? _1.PositionDirection.SHORT
|
|
1569
1572
|
: _1.PositionDirection.LONG;
|
|
1570
1573
|
if (currentSide === _1.PositionDirection.SHORT)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@drift-labs/sdk",
|
|
3
|
-
"version": "2.43.0-beta.
|
|
3
|
+
"version": "2.43.0-beta.11",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"types": "lib/index.d.ts",
|
|
6
6
|
"author": "crispheaney",
|
|
@@ -52,6 +52,7 @@
|
|
|
52
52
|
"@typescript-eslint/eslint-plugin": "^4.28.0",
|
|
53
53
|
"@typescript-eslint/parser": "^4.28.0",
|
|
54
54
|
"chai": "^4.3.6",
|
|
55
|
+
"encoding": "^0.1.13",
|
|
55
56
|
"eslint": "^7.29.0",
|
|
56
57
|
"eslint-config-prettier": "^8.3.0",
|
|
57
58
|
"eslint-plugin-prettier": "^3.4.0",
|
|
@@ -184,6 +184,16 @@ export const DevnetPerpMarkets: PerpMarketConfig[] = [
|
|
|
184
184
|
launchTs: 1698074659000,
|
|
185
185
|
oracleSource: OracleSource.PYTH,
|
|
186
186
|
},
|
|
187
|
+
{
|
|
188
|
+
fullName: 'Rollbit',
|
|
189
|
+
category: ['Exchange'],
|
|
190
|
+
symbol: 'RLB-PERP',
|
|
191
|
+
baseAssetSymbol: 'RLB',
|
|
192
|
+
marketIndex: 17,
|
|
193
|
+
oracle: new PublicKey('6BmJozusMugAySsfNfMFsU1YRWcGwyP3oycNX9Pv9oCz'),
|
|
194
|
+
launchTs: 11699265968000,
|
|
195
|
+
oracleSource: OracleSource.PYTH,
|
|
196
|
+
},
|
|
187
197
|
];
|
|
188
198
|
|
|
189
199
|
export const MainnetPerpMarkets: PerpMarketConfig[] = [
|
|
@@ -357,6 +367,16 @@ export const MainnetPerpMarkets: PerpMarketConfig[] = [
|
|
|
357
367
|
launchTs: 1698074659000,
|
|
358
368
|
oracleSource: OracleSource.PYTH,
|
|
359
369
|
},
|
|
370
|
+
{
|
|
371
|
+
fullName: 'Rollbit',
|
|
372
|
+
category: ['Exchange'],
|
|
373
|
+
symbol: 'RLB-PERP',
|
|
374
|
+
baseAssetSymbol: 'RLB',
|
|
375
|
+
marketIndex: 17,
|
|
376
|
+
oracle: new PublicKey('4BA3RcS4zE32WWgp49vvvre2t6nXY1W1kMyKZxeeuUey'),
|
|
377
|
+
launchTs: 11699265968000,
|
|
378
|
+
oracleSource: OracleSource.PYTH,
|
|
379
|
+
},
|
|
360
380
|
];
|
|
361
381
|
|
|
362
382
|
export const PerpMarkets: { [key in DriftEnv]: PerpMarketConfig[] } = {
|
package/src/dlob/DLOB.ts
CHANGED
|
@@ -1111,7 +1111,7 @@ export class DLOB {
|
|
|
1111
1111
|
continue;
|
|
1112
1112
|
}
|
|
1113
1113
|
|
|
1114
|
-
if (filterFcn && filterFcn(bestGenerator.next.value)) {
|
|
1114
|
+
if (filterFcn && !filterFcn(bestGenerator.next.value)) {
|
|
1115
1115
|
bestGenerator.next = bestGenerator.generator.next();
|
|
1116
1116
|
continue;
|
|
1117
1117
|
}
|
|
@@ -1725,6 +1725,7 @@ export class DLOB {
|
|
|
1725
1725
|
return {
|
|
1726
1726
|
bids,
|
|
1727
1727
|
asks,
|
|
1728
|
+
slot,
|
|
1728
1729
|
};
|
|
1729
1730
|
}
|
|
1730
1731
|
|
|
@@ -1785,6 +1786,7 @@ export class DLOB {
|
|
|
1785
1786
|
return {
|
|
1786
1787
|
bids,
|
|
1787
1788
|
asks,
|
|
1789
|
+
slot,
|
|
1788
1790
|
};
|
|
1789
1791
|
}
|
|
1790
1792
|
|
|
@@ -29,6 +29,7 @@ export type L2Level = {
|
|
|
29
29
|
export type L2OrderBook = {
|
|
30
30
|
asks: L2Level[];
|
|
31
31
|
bids: L2Level[];
|
|
32
|
+
slot?: number;
|
|
32
33
|
};
|
|
33
34
|
|
|
34
35
|
export interface L2OrderBookGenerator {
|
|
@@ -46,6 +47,7 @@ export type L3Level = {
|
|
|
46
47
|
export type L3OrderBook = {
|
|
47
48
|
asks: L3Level[];
|
|
48
49
|
bids: L3Level[];
|
|
50
|
+
slot?: number;
|
|
49
51
|
};
|
|
50
52
|
|
|
51
53
|
export const DEFAULT_TOP_OF_BOOK_QUOTE_AMOUNTS = [
|
|
@@ -164,13 +166,22 @@ export function getVammL2Generator({
|
|
|
164
166
|
|
|
165
167
|
const updatedAmm = calculateUpdatedAMM(marketAccount.amm, oraclePriceData);
|
|
166
168
|
|
|
167
|
-
|
|
169
|
+
let [openBids, openAsks] = calculateMarketOpenBidAsk(
|
|
168
170
|
updatedAmm.baseAssetReserve,
|
|
169
171
|
updatedAmm.minBaseAssetReserve,
|
|
170
172
|
updatedAmm.maxBaseAssetReserve,
|
|
171
173
|
updatedAmm.orderStepSize
|
|
172
174
|
);
|
|
173
175
|
|
|
176
|
+
const minOrderSize = marketAccount.amm.orderStepSize;
|
|
177
|
+
if (openBids.lt(minOrderSize.muln(2))) {
|
|
178
|
+
openBids = ZERO;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (openAsks.abs().lt(minOrderSize.muln(2))) {
|
|
182
|
+
openAsks = ZERO;
|
|
183
|
+
}
|
|
184
|
+
|
|
174
185
|
now = now ?? new BN(Date.now() / 1000);
|
|
175
186
|
const [bidReserves, askReserves] = calculateSpreadReserves(
|
|
176
187
|
updatedAmm,
|
|
@@ -354,6 +365,7 @@ export function groupL2(
|
|
|
354
365
|
return {
|
|
355
366
|
bids: groupL2Levels(l2.bids, grouping, PositionDirection.LONG, depth),
|
|
356
367
|
asks: groupL2Levels(l2.asks, grouping, PositionDirection.SHORT, depth),
|
|
368
|
+
slot: l2.slot,
|
|
357
369
|
};
|
|
358
370
|
}
|
|
359
371
|
|
package/src/driftClient.ts
CHANGED
|
@@ -708,6 +708,8 @@ export class DriftClient {
|
|
|
708
708
|
name = DEFAULT_USER_NAME,
|
|
709
709
|
referrerInfo?: ReferrerInfo
|
|
710
710
|
): Promise<[TransactionSignature, PublicKey]> {
|
|
711
|
+
const initializeIxs = [];
|
|
712
|
+
|
|
711
713
|
const [userAccountPublicKey, initializeUserAccountIx] =
|
|
712
714
|
await this.getInitializeUserInstructions(
|
|
713
715
|
subAccountId,
|
|
@@ -715,15 +717,16 @@ export class DriftClient {
|
|
|
715
717
|
referrerInfo
|
|
716
718
|
);
|
|
717
719
|
|
|
718
|
-
const tx = new Transaction();
|
|
719
720
|
if (subAccountId === 0) {
|
|
720
721
|
if (
|
|
721
722
|
!(await this.checkIfAccountExists(this.getUserStatsAccountPublicKey()))
|
|
722
723
|
) {
|
|
723
|
-
|
|
724
|
+
initializeIxs.push(await this.getInitializeUserStatsIx());
|
|
724
725
|
}
|
|
725
726
|
}
|
|
726
|
-
|
|
727
|
+
initializeIxs.push(initializeUserAccountIx);
|
|
728
|
+
const tx = await this.buildTransaction(initializeIxs);
|
|
729
|
+
|
|
727
730
|
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
728
731
|
|
|
729
732
|
await this.addUser(subAccountId);
|
|
@@ -1800,6 +1803,8 @@ export class DriftClient {
|
|
|
1800
1803
|
referrerInfo?: ReferrerInfo,
|
|
1801
1804
|
txParams?: TxParams
|
|
1802
1805
|
): Promise<[TransactionSignature, PublicKey]> {
|
|
1806
|
+
const ixs = [];
|
|
1807
|
+
|
|
1803
1808
|
const [userAccountPublicKey, initializeUserAccountIx] =
|
|
1804
1809
|
await this.getInitializeUserInstructions(
|
|
1805
1810
|
subAccountId,
|
|
@@ -1813,20 +1818,15 @@ export class DriftClient {
|
|
|
1813
1818
|
|
|
1814
1819
|
const isSolMarket = spotMarket.mint.equals(WRAPPED_SOL_MINT);
|
|
1815
1820
|
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
ComputeBudgetProgram.setComputeUnitLimit({
|
|
1820
|
-
units: txParams?.computeUnits ?? 600_000,
|
|
1821
|
-
})
|
|
1822
|
-
);
|
|
1821
|
+
let params: TxParams = {
|
|
1822
|
+
computeUnits: txParams?.computeUnits ?? 600_000,
|
|
1823
|
+
};
|
|
1823
1824
|
|
|
1824
1825
|
if (txParams?.computeUnitsPrice) {
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
);
|
|
1826
|
+
params = {
|
|
1827
|
+
...params,
|
|
1828
|
+
computeUnitsPrice: txParams.computeUnitsPrice,
|
|
1829
|
+
};
|
|
1830
1830
|
}
|
|
1831
1831
|
|
|
1832
1832
|
const authority = this.wallet.publicKey;
|
|
@@ -1845,9 +1845,7 @@ export class DriftClient {
|
|
|
1845
1845
|
|
|
1846
1846
|
userTokenAccount = pubkey;
|
|
1847
1847
|
|
|
1848
|
-
|
|
1849
|
-
tx.add(ix);
|
|
1850
|
-
});
|
|
1848
|
+
ixs.push(...startIxs);
|
|
1851
1849
|
}
|
|
1852
1850
|
|
|
1853
1851
|
const depositCollateralIx = isFromSubaccount
|
|
@@ -1870,14 +1868,14 @@ export class DriftClient {
|
|
|
1870
1868
|
if (
|
|
1871
1869
|
!(await this.checkIfAccountExists(this.getUserStatsAccountPublicKey()))
|
|
1872
1870
|
) {
|
|
1873
|
-
|
|
1871
|
+
ixs.push(await this.getInitializeUserStatsIx());
|
|
1874
1872
|
}
|
|
1875
1873
|
}
|
|
1876
|
-
|
|
1874
|
+
ixs.push(initializeUserAccountIx, depositCollateralIx);
|
|
1877
1875
|
|
|
1878
1876
|
// Close the wrapped sol account at the end of the transaction
|
|
1879
1877
|
if (createWSOLTokenAccount) {
|
|
1880
|
-
|
|
1878
|
+
ixs.push(
|
|
1881
1879
|
createCloseAccountInstruction(
|
|
1882
1880
|
userTokenAccount,
|
|
1883
1881
|
authority,
|
|
@@ -1887,6 +1885,8 @@ export class DriftClient {
|
|
|
1887
1885
|
);
|
|
1888
1886
|
}
|
|
1889
1887
|
|
|
1888
|
+
const tx = await this.buildTransaction(ixs, params);
|
|
1889
|
+
|
|
1890
1890
|
const { txSig, slot } = await this.sendTransaction(
|
|
1891
1891
|
tx,
|
|
1892
1892
|
additionalSigners,
|
|
@@ -1907,6 +1907,8 @@ export class DriftClient {
|
|
|
1907
1907
|
amount: BN,
|
|
1908
1908
|
referrerInfo?: ReferrerInfo
|
|
1909
1909
|
): Promise<[TransactionSignature, PublicKey]> {
|
|
1910
|
+
const ixs = [];
|
|
1911
|
+
|
|
1910
1912
|
const [associateTokenPublicKey, createAssociatedAccountIx, mintToIx] =
|
|
1911
1913
|
await tokenFaucet.createAssociatedTokenAccountAndMintToInstructions(
|
|
1912
1914
|
this.wallet.publicKey,
|
|
@@ -1929,18 +1931,20 @@ export class DriftClient {
|
|
|
1929
1931
|
false
|
|
1930
1932
|
);
|
|
1931
1933
|
|
|
1932
|
-
|
|
1934
|
+
ixs.push(createAssociatedAccountIx, mintToIx);
|
|
1933
1935
|
|
|
1934
1936
|
if (subAccountId === 0) {
|
|
1935
1937
|
if (
|
|
1936
1938
|
!(await this.checkIfAccountExists(this.getUserStatsAccountPublicKey()))
|
|
1937
1939
|
) {
|
|
1938
|
-
|
|
1940
|
+
ixs.push(await this.getInitializeUserStatsIx());
|
|
1939
1941
|
}
|
|
1940
1942
|
}
|
|
1941
|
-
|
|
1943
|
+
ixs.push(initializeUserAccountIx, depositCollateralIx);
|
|
1944
|
+
|
|
1945
|
+
const tx = await this.buildTransaction(ixs);
|
|
1942
1946
|
|
|
1943
|
-
const txSig = await this.
|
|
1947
|
+
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
1944
1948
|
|
|
1945
1949
|
await this.addUser(subAccountId);
|
|
1946
1950
|
|
|
@@ -1960,12 +1964,7 @@ export class DriftClient {
|
|
|
1960
1964
|
associatedTokenAddress: PublicKey,
|
|
1961
1965
|
reduceOnly = false
|
|
1962
1966
|
): Promise<TransactionSignature> {
|
|
1963
|
-
const
|
|
1964
|
-
tx.add(
|
|
1965
|
-
ComputeBudgetProgram.setComputeUnitLimit({
|
|
1966
|
-
units: 600_000,
|
|
1967
|
-
})
|
|
1968
|
-
);
|
|
1967
|
+
const withdrawIxs = [];
|
|
1969
1968
|
|
|
1970
1969
|
const additionalSigners: Array<Signer> = [];
|
|
1971
1970
|
|
|
@@ -1986,9 +1985,7 @@ export class DriftClient {
|
|
|
1986
1985
|
|
|
1987
1986
|
associatedTokenAddress = pubkey;
|
|
1988
1987
|
|
|
1989
|
-
|
|
1990
|
-
tx.add(ix);
|
|
1991
|
-
});
|
|
1988
|
+
withdrawIxs.push(...ixs);
|
|
1992
1989
|
} else {
|
|
1993
1990
|
const accountExists = await this.checkIfAccountExists(
|
|
1994
1991
|
associatedTokenAddress
|
|
@@ -2001,22 +1998,22 @@ export class DriftClient {
|
|
|
2001
1998
|
associatedTokenAddress
|
|
2002
1999
|
);
|
|
2003
2000
|
|
|
2004
|
-
|
|
2001
|
+
withdrawIxs.push(createAssociatedTokenAccountIx);
|
|
2005
2002
|
}
|
|
2006
2003
|
}
|
|
2007
2004
|
|
|
2008
|
-
const
|
|
2005
|
+
const withdrawCollateralIx = await this.getWithdrawIx(
|
|
2009
2006
|
amount,
|
|
2010
2007
|
spotMarketAccount.marketIndex,
|
|
2011
2008
|
associatedTokenAddress,
|
|
2012
2009
|
reduceOnly
|
|
2013
2010
|
);
|
|
2014
2011
|
|
|
2015
|
-
|
|
2012
|
+
withdrawIxs.push(withdrawCollateralIx);
|
|
2016
2013
|
|
|
2017
2014
|
// Close the wrapped sol account at the end of the transaction
|
|
2018
2015
|
if (createWSOLTokenAccount) {
|
|
2019
|
-
|
|
2016
|
+
withdrawIxs.push(
|
|
2020
2017
|
createCloseAccountInstruction(
|
|
2021
2018
|
associatedTokenAddress,
|
|
2022
2019
|
authority,
|
|
@@ -2026,6 +2023,9 @@ export class DriftClient {
|
|
|
2026
2023
|
);
|
|
2027
2024
|
}
|
|
2028
2025
|
|
|
2026
|
+
const tx = await this.buildTransaction(withdrawIxs, {
|
|
2027
|
+
computeUnits: 600_000,
|
|
2028
|
+
});
|
|
2029
2029
|
const { txSig, slot } = await this.sendTransaction(
|
|
2030
2030
|
tx,
|
|
2031
2031
|
additionalSigners,
|
|
@@ -4758,13 +4758,8 @@ export class DriftClient {
|
|
|
4758
4758
|
marketIndexes: number[]
|
|
4759
4759
|
): Promise<TransactionSignature> {
|
|
4760
4760
|
const ixs = await this.getSettlePNLsIxs(users, marketIndexes);
|
|
4761
|
-
|
|
4762
|
-
|
|
4763
|
-
ComputeBudgetProgram.setComputeUnitLimit({
|
|
4764
|
-
units: 1_000_000,
|
|
4765
|
-
})
|
|
4766
|
-
)
|
|
4767
|
-
.add(...ixs);
|
|
4761
|
+
|
|
4762
|
+
const tx = await this.buildTransaction(ixs, { computeUnits: 1_000_000 });
|
|
4768
4763
|
|
|
4769
4764
|
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
4770
4765
|
return txSig;
|
|
@@ -5484,7 +5479,7 @@ export class DriftClient {
|
|
|
5484
5479
|
*/
|
|
5485
5480
|
fromSubaccount?: boolean;
|
|
5486
5481
|
}): Promise<TransactionSignature> {
|
|
5487
|
-
const
|
|
5482
|
+
const addIfStakeIxs = [];
|
|
5488
5483
|
|
|
5489
5484
|
const additionalSigners: Array<Signer> = [];
|
|
5490
5485
|
const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
|
|
@@ -5501,7 +5496,7 @@ export class DriftClient {
|
|
|
5501
5496
|
);
|
|
5502
5497
|
tokenAccount = pubkey;
|
|
5503
5498
|
ixs.forEach((ix) => {
|
|
5504
|
-
|
|
5499
|
+
addIfStakeIxs.push(ix);
|
|
5505
5500
|
});
|
|
5506
5501
|
} else {
|
|
5507
5502
|
tokenAccount = collateralAccountPublicKey;
|
|
@@ -5513,14 +5508,14 @@ export class DriftClient {
|
|
|
5513
5508
|
marketIndex,
|
|
5514
5509
|
tokenAccount
|
|
5515
5510
|
);
|
|
5516
|
-
|
|
5511
|
+
addIfStakeIxs.push(withdrawIx);
|
|
5517
5512
|
}
|
|
5518
5513
|
|
|
5519
5514
|
if (initializeStakeAccount) {
|
|
5520
5515
|
const initializeIx = await this.getInitializeInsuranceFundStakeIx(
|
|
5521
5516
|
marketIndex
|
|
5522
5517
|
);
|
|
5523
|
-
|
|
5518
|
+
addIfStakeIxs.push(initializeIx);
|
|
5524
5519
|
}
|
|
5525
5520
|
|
|
5526
5521
|
const addFundsIx = await this.getAddInsuranceFundStakeIx(
|
|
@@ -5529,10 +5524,10 @@ export class DriftClient {
|
|
|
5529
5524
|
tokenAccount
|
|
5530
5525
|
);
|
|
5531
5526
|
|
|
5532
|
-
|
|
5527
|
+
addIfStakeIxs.push(addFundsIx);
|
|
5533
5528
|
|
|
5534
5529
|
if (createWSOLTokenAccount) {
|
|
5535
|
-
|
|
5530
|
+
addIfStakeIxs.push(
|
|
5536
5531
|
createCloseAccountInstruction(
|
|
5537
5532
|
tokenAccount,
|
|
5538
5533
|
this.wallet.publicKey,
|
|
@@ -5542,6 +5537,8 @@ export class DriftClient {
|
|
|
5542
5537
|
);
|
|
5543
5538
|
}
|
|
5544
5539
|
|
|
5540
|
+
const tx = await this.buildTransaction(addIfStakeIxs);
|
|
5541
|
+
|
|
5545
5542
|
const { txSig } = await this.sendTransaction(
|
|
5546
5543
|
tx,
|
|
5547
5544
|
additionalSigners,
|
|
@@ -5568,7 +5565,7 @@ export class DriftClient {
|
|
|
5568
5565
|
writableSpotMarketIndexes: [marketIndex],
|
|
5569
5566
|
});
|
|
5570
5567
|
|
|
5571
|
-
const
|
|
5568
|
+
const ix = await this.program.instruction.requestRemoveInsuranceFundStake(
|
|
5572
5569
|
marketIndex,
|
|
5573
5570
|
amount,
|
|
5574
5571
|
{
|
|
@@ -5584,6 +5581,8 @@ export class DriftClient {
|
|
|
5584
5581
|
}
|
|
5585
5582
|
);
|
|
5586
5583
|
|
|
5584
|
+
const tx = await this.buildTransaction(ix);
|
|
5585
|
+
|
|
5587
5586
|
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
5588
5587
|
return txSig;
|
|
5589
5588
|
}
|
|
@@ -5604,8 +5603,8 @@ export class DriftClient {
|
|
|
5604
5603
|
writableSpotMarketIndexes: [marketIndex],
|
|
5605
5604
|
});
|
|
5606
5605
|
|
|
5607
|
-
const
|
|
5608
|
-
await this.program.
|
|
5606
|
+
const ix =
|
|
5607
|
+
await this.program.instruction.cancelRequestRemoveInsuranceFundStake(
|
|
5609
5608
|
marketIndex,
|
|
5610
5609
|
{
|
|
5611
5610
|
accounts: {
|
|
@@ -5620,6 +5619,8 @@ export class DriftClient {
|
|
|
5620
5619
|
}
|
|
5621
5620
|
);
|
|
5622
5621
|
|
|
5622
|
+
const tx = await this.buildTransaction(ix);
|
|
5623
|
+
|
|
5623
5624
|
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
5624
5625
|
return txSig;
|
|
5625
5626
|
}
|
|
@@ -5628,7 +5629,7 @@ export class DriftClient {
|
|
|
5628
5629
|
marketIndex: number,
|
|
5629
5630
|
collateralAccountPublicKey: PublicKey
|
|
5630
5631
|
): Promise<TransactionSignature> {
|
|
5631
|
-
const
|
|
5632
|
+
const removeIfStakeIxs = [];
|
|
5632
5633
|
const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
|
|
5633
5634
|
const ifStakeAccountPublicKey = getInsuranceFundStakeAccountPublicKey(
|
|
5634
5635
|
this.program.programId,
|
|
@@ -5650,7 +5651,7 @@ export class DriftClient {
|
|
|
5650
5651
|
);
|
|
5651
5652
|
tokenAccount = pubkey;
|
|
5652
5653
|
ixs.forEach((ix) => {
|
|
5653
|
-
|
|
5654
|
+
removeIfStakeIxs.push(ix);
|
|
5654
5655
|
});
|
|
5655
5656
|
} else {
|
|
5656
5657
|
tokenAccount = collateralAccountPublicKey;
|
|
@@ -5678,11 +5679,11 @@ export class DriftClient {
|
|
|
5678
5679
|
remainingAccounts,
|
|
5679
5680
|
});
|
|
5680
5681
|
|
|
5681
|
-
|
|
5682
|
+
removeIfStakeIxs.push(removeStakeIx);
|
|
5682
5683
|
|
|
5683
5684
|
// Close the wrapped sol account at the end of the transaction
|
|
5684
5685
|
if (createWSOLTokenAccount) {
|
|
5685
|
-
|
|
5686
|
+
removeIfStakeIxs.push(
|
|
5686
5687
|
createCloseAccountInstruction(
|
|
5687
5688
|
tokenAccount,
|
|
5688
5689
|
this.wallet.publicKey,
|
|
@@ -5692,6 +5693,8 @@ export class DriftClient {
|
|
|
5692
5693
|
);
|
|
5693
5694
|
}
|
|
5694
5695
|
|
|
5696
|
+
const tx = await this.buildTransaction(removeIfStakeIxs);
|
|
5697
|
+
|
|
5695
5698
|
const { txSig } = await this.sendTransaction(
|
|
5696
5699
|
tx,
|
|
5697
5700
|
additionalSigners,
|
|
@@ -5711,7 +5714,7 @@ export class DriftClient {
|
|
|
5711
5714
|
writableSpotMarketIndexes: [marketIndex],
|
|
5712
5715
|
});
|
|
5713
5716
|
|
|
5714
|
-
const
|
|
5717
|
+
const ix = await this.program.instruction.settleRevenueToInsuranceFund(
|
|
5715
5718
|
marketIndex,
|
|
5716
5719
|
{
|
|
5717
5720
|
accounts: {
|
|
@@ -5726,6 +5729,8 @@ export class DriftClient {
|
|
|
5726
5729
|
}
|
|
5727
5730
|
);
|
|
5728
5731
|
|
|
5732
|
+
const tx = await this.buildTransaction(ix);
|
|
5733
|
+
|
|
5729
5734
|
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
5730
5735
|
return txSig;
|
|
5731
5736
|
}
|
package/src/user.ts
CHANGED
|
@@ -2884,8 +2884,12 @@ export class User {
|
|
|
2884
2884
|
includeOpenOrders
|
|
2885
2885
|
);
|
|
2886
2886
|
|
|
2887
|
+
const worstCaseBase = calculateWorstCaseBaseAssetAmount(currentPosition);
|
|
2888
|
+
|
|
2889
|
+
// current side is short if position base asset amount is negative OR there is no position open but open orders are short
|
|
2887
2890
|
const currentSide =
|
|
2888
|
-
currentPosition
|
|
2891
|
+
currentPosition.baseAssetAmount.isNeg() ||
|
|
2892
|
+
(currentPosition.baseAssetAmount.eq(ZERO) && worstCaseBase.isNeg())
|
|
2889
2893
|
? PositionDirection.SHORT
|
|
2890
2894
|
: PositionDirection.LONG;
|
|
2891
2895
|
|
package/tests/amm/test.ts
CHANGED
|
@@ -956,4 +956,82 @@ describe('AMM Tests', () => {
|
|
|
956
956
|
);
|
|
957
957
|
assert(totalAskSize.sub(openAsks.abs()).lte(new BN(5))); // only tiny rounding errors
|
|
958
958
|
});
|
|
959
|
+
|
|
960
|
+
it('orderbook L2 gen (no topOfBookQuoteAmounts, 10 numOrders, no liquidity)', async () => {
|
|
961
|
+
const myMockPerpMarkets = _.cloneDeep(mockPerpMarkets);
|
|
962
|
+
|
|
963
|
+
const mockMarket1: PerpMarketAccount = myMockPerpMarkets[0];
|
|
964
|
+
const cc = 38104569;
|
|
965
|
+
mockMarket1.amm.baseAssetReserve = new BN(cc).mul(BASE_PRECISION);
|
|
966
|
+
mockMarket1.amm.minOrderSize = new BN(5);
|
|
967
|
+
mockMarket1.amm.maxBaseAssetReserve = mockMarket1.amm.baseAssetReserve.add(
|
|
968
|
+
new BN(9)
|
|
969
|
+
);
|
|
970
|
+
mockMarket1.amm.minBaseAssetReserve =
|
|
971
|
+
mockMarket1.amm.baseAssetReserve.sub(new BN(9));
|
|
972
|
+
mockMarket1.amm.quoteAssetReserve = new BN(cc).mul(BASE_PRECISION);
|
|
973
|
+
mockMarket1.amm.pegMultiplier = new BN(18.32 * PEG_PRECISION.toNumber());
|
|
974
|
+
mockMarket1.amm.sqrtK = new BN(cc).mul(BASE_PRECISION);
|
|
975
|
+
|
|
976
|
+
const now = new BN(1688881915);
|
|
977
|
+
|
|
978
|
+
const oraclePriceData: OraclePriceData = {
|
|
979
|
+
price: new BN(18.624 * PRICE_PRECISION.toNumber()),
|
|
980
|
+
slot: new BN(0),
|
|
981
|
+
confidence: new BN(1),
|
|
982
|
+
hasSufficientNumberOfDataPoints: true,
|
|
983
|
+
};
|
|
984
|
+
mockMarket1.amm.historicalOracleData.lastOraclePrice = new BN(
|
|
985
|
+
18.5535 * PRICE_PRECISION.toNumber()
|
|
986
|
+
);
|
|
987
|
+
|
|
988
|
+
const updatedAmm = calculateUpdatedAMM(mockMarket1.amm, oraclePriceData);
|
|
989
|
+
|
|
990
|
+
const [openBids, openAsks] = calculateMarketOpenBidAsk(
|
|
991
|
+
updatedAmm.baseAssetReserve,
|
|
992
|
+
updatedAmm.minBaseAssetReserve,
|
|
993
|
+
updatedAmm.maxBaseAssetReserve,
|
|
994
|
+
updatedAmm.orderStepSize
|
|
995
|
+
);
|
|
996
|
+
|
|
997
|
+
const generator = getVammL2Generator({
|
|
998
|
+
marketAccount: mockMarket1,
|
|
999
|
+
oraclePriceData,
|
|
1000
|
+
numOrders: 10,
|
|
1001
|
+
now,
|
|
1002
|
+
topOfBookQuoteAmounts: [],
|
|
1003
|
+
});
|
|
1004
|
+
|
|
1005
|
+
const bids = Array.from(generator.getL2Bids());
|
|
1006
|
+
// console.log(bids);
|
|
1007
|
+
|
|
1008
|
+
const totalBidSize = bids.reduce((total: BN, order: L2Level) => {
|
|
1009
|
+
return total.add(order.size);
|
|
1010
|
+
}, ZERO);
|
|
1011
|
+
|
|
1012
|
+
console.log(
|
|
1013
|
+
'totalBidSize:',
|
|
1014
|
+
totalBidSize.toString(),
|
|
1015
|
+
'openBids:',
|
|
1016
|
+
openBids.toString()
|
|
1017
|
+
);
|
|
1018
|
+
assert(openBids.eq(new BN(9)));
|
|
1019
|
+
assert(totalBidSize.eq(ZERO));
|
|
1020
|
+
|
|
1021
|
+
const asks = Array.from(generator.getL2Asks());
|
|
1022
|
+
// console.log(asks);
|
|
1023
|
+
|
|
1024
|
+
const totalAskSize = asks.reduce((total: BN, order: L2Level) => {
|
|
1025
|
+
return total.add(order.size);
|
|
1026
|
+
}, ZERO);
|
|
1027
|
+
console.log(
|
|
1028
|
+
'totalAskSize:',
|
|
1029
|
+
totalAskSize.toString(),
|
|
1030
|
+
'openAsks:',
|
|
1031
|
+
openAsks.toString()
|
|
1032
|
+
);
|
|
1033
|
+
|
|
1034
|
+
assert(openAsks.eq(new BN(-9)));
|
|
1035
|
+
assert(totalAskSize.eq(ZERO));
|
|
1036
|
+
});
|
|
959
1037
|
});
|
package/tests/user/test.ts
CHANGED
|
@@ -289,8 +289,9 @@ describe('User Tests', () => {
|
|
|
289
289
|
mockUser.getMaxLeverageForPerp(0).toString()
|
|
290
290
|
);
|
|
291
291
|
assert(mockUser.getMaxLeverageForPerp(0).eq(new BN('50000'))); // 5x
|
|
292
|
-
assert(
|
|
293
|
-
|
|
292
|
+
assert(
|
|
293
|
+
mockUser.getMaxLeverageForPerp(0, 'Maintenance').eq(new BN('100000'))
|
|
294
|
+
); // 10x
|
|
294
295
|
});
|
|
295
296
|
|
|
296
297
|
it('worst case token amount', async () => {
|
|
@@ -399,8 +400,7 @@ describe('User Tests', () => {
|
|
|
399
400
|
); // -$2k
|
|
400
401
|
});
|
|
401
402
|
|
|
402
|
-
|
|
403
|
-
it('custom margin ratio (sol spot)', async() => {
|
|
403
|
+
it('custom margin ratio (sol spot)', async () => {
|
|
404
404
|
const myMockUserAccount = _.cloneDeep(mockUserAccount);
|
|
405
405
|
|
|
406
406
|
const solMarket = Object.assign({}, _.cloneDeep(mockSpotMarkets[1]), {
|
|
@@ -427,12 +427,10 @@ describe('User Tests', () => {
|
|
|
427
427
|
);
|
|
428
428
|
|
|
429
429
|
console.log(worstCase);
|
|
430
|
-
assert(worstCase.weight.eq(new BN(8000)));
|
|
431
|
-
|
|
430
|
+
assert(worstCase.weight.eq(new BN(8000)));
|
|
432
431
|
|
|
433
432
|
myMockUserAccount.maxMarginRatio = MARGIN_PRECISION.toNumber(); // max 1x pls
|
|
434
433
|
|
|
435
|
-
|
|
436
434
|
const worstCaseAfter = getWorstCaseTokenAmounts(
|
|
437
435
|
spotPosition,
|
|
438
436
|
solMarket,
|
|
@@ -443,10 +441,9 @@ describe('User Tests', () => {
|
|
|
443
441
|
|
|
444
442
|
console.log(worstCaseAfter);
|
|
445
443
|
assert(worstCaseAfter.weight.eq(new BN(0))); // not allowed to increase exposure
|
|
446
|
-
|
|
447
444
|
});
|
|
448
445
|
|
|
449
|
-
it('custom margin ratio (sol perp)', async() => {
|
|
446
|
+
it('custom margin ratio (sol perp)', async () => {
|
|
450
447
|
const myMockPerpMarkets = _.cloneDeep(mockPerpMarkets);
|
|
451
448
|
const myMockSpotMarkets = _.cloneDeep(mockSpotMarkets);
|
|
452
449
|
const myMockUserAccount = _.cloneDeep(mockUserAccount);
|
|
@@ -469,7 +466,6 @@ describe('User Tests', () => {
|
|
|
469
466
|
[1, 1, 1, 1, 1, 1, 1, 1]
|
|
470
467
|
);
|
|
471
468
|
|
|
472
|
-
|
|
473
469
|
assert(mockUser.getTokenAmount(0).eq(new BN('10000000000')));
|
|
474
470
|
assert(mockUser.getNetSpotMarketValue().eq(new BN('10000000000')));
|
|
475
471
|
assert(
|
|
@@ -486,7 +482,9 @@ describe('User Tests', () => {
|
|
|
486
482
|
assert(iLev == 5000);
|
|
487
483
|
assert(mLev == 10000);
|
|
488
484
|
|
|
489
|
-
myMockUserAccount.maxMarginRatio = MARGIN_PRECISION.div(
|
|
485
|
+
myMockUserAccount.maxMarginRatio = MARGIN_PRECISION.div(
|
|
486
|
+
new BN(2)
|
|
487
|
+
).toNumber(); // 2x max pls
|
|
490
488
|
|
|
491
489
|
const mockUser2: User = await makeMockUser(
|
|
492
490
|
myMockPerpMarkets,
|
|
@@ -498,9 +496,8 @@ describe('User Tests', () => {
|
|
|
498
496
|
iLev = mockUser2.getMaxLeverageForPerp(0, 'Initial').toNumber();
|
|
499
497
|
mLev = mockUser2.getMaxLeverageForPerp(0, 'Maintenance').toNumber();
|
|
500
498
|
console.log(iLev, mLev);
|
|
501
|
-
|
|
499
|
+
|
|
502
500
|
assert(iLev == 2000);
|
|
503
501
|
assert(mLev == 10000);
|
|
504
|
-
|
|
505
502
|
});
|
|
506
503
|
});
|