@drift-labs/sdk 2.43.0-beta.9 → 2.44.0-beta.0
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/VERSION +1 -1
- package/lib/accounts/webSocketAccountSubscriber.d.ts +1 -0
- package/lib/accounts/webSocketAccountSubscriber.js +18 -3
- package/lib/accounts/webSocketProgramAccountSubscriber.d.ts +1 -0
- package/lib/accounts/webSocketProgramAccountSubscriber.js +18 -3
- package/lib/adminClient.d.ts +1 -0
- package/lib/adminClient.js +8 -0
- package/lib/dlob/DLOB.d.ts +9 -3
- package/lib/dlob/DLOB.js +77 -14
- package/lib/dlob/orderBookLevels.js +1 -0
- package/lib/driftClient.d.ts +3 -1
- package/lib/driftClient.js +86 -69
- package/lib/idl/drift.json +22 -1
- package/lib/jupiter/jupiterClient.js +10 -2
- package/lib/math/amm.js +2 -1
- package/lib/math/trade.js +18 -24
- package/lib/tx/fastSingleTxSender.js +6 -1
- package/lib/user.js +7 -8
- package/package.json +1 -1
- package/src/accounts/webSocketAccountSubscriber.ts +20 -6
- package/src/accounts/webSocketProgramAccountSubscriber.ts +19 -6
- package/src/adminClient.ts +14 -0
- package/src/dlob/DLOB.ts +114 -20
- package/src/dlob/orderBookLevels.ts +1 -0
- package/src/driftClient.ts +129 -82
- package/src/idl/drift.json +22 -1
- package/src/jupiter/jupiterClient.ts +12 -2
- package/src/math/amm.ts +2 -2
- package/src/math/trade.ts +26 -26
- package/src/tx/fastSingleTxSender.ts +7 -3
- package/src/user.ts +12 -8
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;
|
|
@@ -1365,9 +1366,10 @@ class DriftClient {
|
|
|
1365
1366
|
* @param makerInfo
|
|
1366
1367
|
* @param txParams
|
|
1367
1368
|
* @param bracketOrdersParams
|
|
1369
|
+
* @param cancelExistingOrders - Builds and returns an extra transaciton to cancel the existing orders in the same perp market. Intended use is to auto-cancel TP/SL orders when closing a position. Ignored if orderParams.marketType is not MarketType.PERP
|
|
1368
1370
|
* @returns
|
|
1369
1371
|
*/
|
|
1370
|
-
async sendMarketOrderAndGetSignedFillTx(orderParams, userAccountPublicKey, userAccount, makerInfo, txParams, bracketOrdersParams = new Array(), referrerInfo) {
|
|
1372
|
+
async sendMarketOrderAndGetSignedFillTx(orderParams, userAccountPublicKey, userAccount, makerInfo, txParams, bracketOrdersParams = new Array(), referrerInfo, cancelExistingOrders) {
|
|
1371
1373
|
const marketIndex = orderParams.marketIndex;
|
|
1372
1374
|
const orderId = userAccount.nextOrderId;
|
|
1373
1375
|
const bracketOrderIxs = [];
|
|
@@ -1380,20 +1382,31 @@ class DriftClient {
|
|
|
1380
1382
|
orderId,
|
|
1381
1383
|
marketIndex,
|
|
1382
1384
|
}, makerInfo, referrerInfo);
|
|
1385
|
+
let cancelOrdersIx;
|
|
1386
|
+
let cancelExistingOrdersTx;
|
|
1387
|
+
if (cancelExistingOrders && (0, types_1.isVariant)(orderParams.marketType, 'perp')) {
|
|
1388
|
+
cancelOrdersIx = await this.getCancelOrdersIx(orderParams.marketType, orderParams.marketIndex, null);
|
|
1389
|
+
//@ts-ignore
|
|
1390
|
+
cancelExistingOrdersTx = await this.buildTransaction([cancelOrdersIx], txParams, this.txVersion);
|
|
1391
|
+
}
|
|
1383
1392
|
// use versioned transactions if there is a lookup table account and wallet is compatible
|
|
1384
1393
|
if (this.txVersion === 0) {
|
|
1385
1394
|
const versionedMarketOrderTx = await this.buildTransaction([placePerpOrderIx].concat(bracketOrderIxs), txParams, 0);
|
|
1386
1395
|
const versionedFillTx = await this.buildTransaction([fillPerpOrderIx], txParams, 0);
|
|
1387
|
-
const [signedVersionedMarketOrderTx, signedVersionedFillTx] = await this.provider.wallet.signAllTransactions([
|
|
1388
|
-
//@ts-ignore
|
|
1396
|
+
const [signedVersionedMarketOrderTx, signedVersionedFillTx, signedCancelExistingOrdersTx,] = await this.provider.wallet.signAllTransactions([
|
|
1389
1397
|
versionedMarketOrderTx,
|
|
1390
|
-
//@ts-ignore
|
|
1391
1398
|
versionedFillTx,
|
|
1392
|
-
|
|
1399
|
+
cancelExistingOrdersTx,
|
|
1400
|
+
].filter((tx) => tx !== undefined));
|
|
1393
1401
|
const { txSig, slot } = await this.txSender.sendRawTransaction(signedVersionedMarketOrderTx.serialize(), this.opts);
|
|
1394
1402
|
this.perpMarketLastSlotCache.set(orderParams.marketIndex, slot);
|
|
1395
|
-
|
|
1396
|
-
|
|
1403
|
+
return {
|
|
1404
|
+
txSig,
|
|
1405
|
+
// @ts-ignore
|
|
1406
|
+
signedFillTx: signedVersionedFillTx,
|
|
1407
|
+
// @ts-ignore
|
|
1408
|
+
signedCancelExistingOrdersTx,
|
|
1409
|
+
};
|
|
1397
1410
|
}
|
|
1398
1411
|
else {
|
|
1399
1412
|
const marketOrderTx = (0, utils_1.wrapInTx)(placePerpOrderIx, txParams === null || txParams === void 0 ? void 0 : txParams.computeUnits, txParams === null || txParams === void 0 ? void 0 : txParams.computeUnitsPrice);
|
|
@@ -1407,10 +1420,10 @@ class DriftClient {
|
|
|
1407
1420
|
fillTx.recentBlockhash = currentBlockHash;
|
|
1408
1421
|
marketOrderTx.feePayer = userAccount.authority;
|
|
1409
1422
|
fillTx.feePayer = userAccount.authority;
|
|
1410
|
-
const [signedMarketOrderTx, signedFillTx] = await this.provider.wallet.signAllTransactions([marketOrderTx, fillTx]);
|
|
1423
|
+
const [signedMarketOrderTx, signedFillTx, signedCancelExistingOrdersTx] = await this.provider.wallet.signAllTransactions([marketOrderTx, fillTx, cancelExistingOrdersTx].filter((tx) => tx !== undefined));
|
|
1411
1424
|
const { txSig, slot } = await this.sendTransaction(signedMarketOrderTx, [], this.opts, true);
|
|
1412
1425
|
this.perpMarketLastSlotCache.set(orderParams.marketIndex, slot);
|
|
1413
|
-
return { txSig, signedFillTx };
|
|
1426
|
+
return { txSig, signedFillTx, signedCancelExistingOrdersTx };
|
|
1414
1427
|
}
|
|
1415
1428
|
}
|
|
1416
1429
|
async placePerpOrder(orderParams, txParams) {
|
|
@@ -1587,7 +1600,7 @@ class DriftClient {
|
|
|
1587
1600
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
1588
1601
|
let readablePerpMarketIndex = undefined;
|
|
1589
1602
|
let readableSpotMarketIndexes = undefined;
|
|
1590
|
-
if (marketIndex) {
|
|
1603
|
+
if (typeof marketIndex === 'number') {
|
|
1591
1604
|
if (marketType && (0, types_1.isVariant)(marketType, 'perp')) {
|
|
1592
1605
|
readablePerpMarketIndex = marketIndex;
|
|
1593
1606
|
}
|
|
@@ -2107,6 +2120,9 @@ class DriftClient {
|
|
|
2107
2120
|
});
|
|
2108
2121
|
quote = fetchedQuote;
|
|
2109
2122
|
}
|
|
2123
|
+
if (!quote) {
|
|
2124
|
+
throw new Error("Could not fetch Jupiter's quote. Please try again.");
|
|
2125
|
+
}
|
|
2110
2126
|
const transaction = await jupiterClient.getSwap({
|
|
2111
2127
|
quote,
|
|
2112
2128
|
userPublicKey: this.provider.wallet.publicKey,
|
|
@@ -2623,12 +2639,12 @@ class DriftClient {
|
|
|
2623
2639
|
oraclePriceOffset: newOraclePriceOffset || null,
|
|
2624
2640
|
triggerPrice: newTriggerPrice || null,
|
|
2625
2641
|
triggerCondition: newTriggerCondition || null,
|
|
2626
|
-
auctionDuration: auctionDuration ||
|
|
2627
|
-
auctionStartPrice: auctionStartPrice ||
|
|
2628
|
-
auctionEndPrice: auctionEndPrice ||
|
|
2629
|
-
reduceOnly: reduceOnly ||
|
|
2642
|
+
auctionDuration: auctionDuration || 0,
|
|
2643
|
+
auctionStartPrice: auctionStartPrice || numericConstants_1.ZERO,
|
|
2644
|
+
auctionEndPrice: auctionEndPrice || numericConstants_1.ZERO,
|
|
2645
|
+
reduceOnly: reduceOnly || false,
|
|
2630
2646
|
postOnly: postOnly || null,
|
|
2631
|
-
immediateOrCancel: immediateOrCancel ||
|
|
2647
|
+
immediateOrCancel: immediateOrCancel || false,
|
|
2632
2648
|
policy: policy || null,
|
|
2633
2649
|
maxTs: maxTs || null,
|
|
2634
2650
|
};
|
|
@@ -2677,12 +2693,12 @@ class DriftClient {
|
|
|
2677
2693
|
oraclePriceOffset: newOraclePriceOffset || null,
|
|
2678
2694
|
triggerPrice: newTriggerPrice || null,
|
|
2679
2695
|
triggerCondition: newTriggerCondition || null,
|
|
2680
|
-
auctionDuration: auctionDuration ||
|
|
2681
|
-
auctionStartPrice: auctionStartPrice ||
|
|
2682
|
-
auctionEndPrice: auctionEndPrice ||
|
|
2683
|
-
reduceOnly: reduceOnly ||
|
|
2696
|
+
auctionDuration: auctionDuration || 0,
|
|
2697
|
+
auctionStartPrice: auctionStartPrice || numericConstants_1.ZERO,
|
|
2698
|
+
auctionEndPrice: auctionEndPrice || numericConstants_1.ZERO,
|
|
2699
|
+
reduceOnly: reduceOnly || false,
|
|
2684
2700
|
postOnly: postOnly || null,
|
|
2685
|
-
immediateOrCancel: immediateOrCancel ||
|
|
2701
|
+
immediateOrCancel: immediateOrCancel || false,
|
|
2686
2702
|
policy: policy || null,
|
|
2687
2703
|
maxTs: maxTs || null,
|
|
2688
2704
|
};
|
|
@@ -2698,11 +2714,7 @@ class DriftClient {
|
|
|
2698
2714
|
}
|
|
2699
2715
|
async settlePNLs(users, marketIndexes) {
|
|
2700
2716
|
const ixs = await this.getSettlePNLsIxs(users, marketIndexes);
|
|
2701
|
-
const tx =
|
|
2702
|
-
.add(web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
|
|
2703
|
-
units: 1000000,
|
|
2704
|
-
}))
|
|
2705
|
-
.add(...ixs);
|
|
2717
|
+
const tx = await this.buildTransaction(ixs, { computeUnits: 1000000 });
|
|
2706
2718
|
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
2707
2719
|
return txSig;
|
|
2708
2720
|
}
|
|
@@ -3030,7 +3042,7 @@ class DriftClient {
|
|
|
3030
3042
|
* Add to an insurance fund stake and optionally initialize the account
|
|
3031
3043
|
*/
|
|
3032
3044
|
async addInsuranceFundStake({ marketIndex, amount, collateralAccountPublicKey, initializeStakeAccount, fromSubaccount, }) {
|
|
3033
|
-
const
|
|
3045
|
+
const addIfStakeIxs = [];
|
|
3034
3046
|
const additionalSigners = [];
|
|
3035
3047
|
const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
|
|
3036
3048
|
const isSolMarket = spotMarketAccount.mint.equals(spotMarkets_1.WRAPPED_SOL_MINT);
|
|
@@ -3040,7 +3052,7 @@ class DriftClient {
|
|
|
3040
3052
|
const { ixs, pubkey } = await this.getWrappedSolAccountCreationIxs(amount, true);
|
|
3041
3053
|
tokenAccount = pubkey;
|
|
3042
3054
|
ixs.forEach((ix) => {
|
|
3043
|
-
|
|
3055
|
+
addIfStakeIxs.push(ix);
|
|
3044
3056
|
});
|
|
3045
3057
|
}
|
|
3046
3058
|
else {
|
|
@@ -3048,17 +3060,18 @@ class DriftClient {
|
|
|
3048
3060
|
}
|
|
3049
3061
|
if (fromSubaccount) {
|
|
3050
3062
|
const withdrawIx = await this.getWithdrawIx(amount, marketIndex, tokenAccount);
|
|
3051
|
-
|
|
3063
|
+
addIfStakeIxs.push(withdrawIx);
|
|
3052
3064
|
}
|
|
3053
3065
|
if (initializeStakeAccount) {
|
|
3054
3066
|
const initializeIx = await this.getInitializeInsuranceFundStakeIx(marketIndex);
|
|
3055
|
-
|
|
3067
|
+
addIfStakeIxs.push(initializeIx);
|
|
3056
3068
|
}
|
|
3057
3069
|
const addFundsIx = await this.getAddInsuranceFundStakeIx(marketIndex, amount, tokenAccount);
|
|
3058
|
-
|
|
3070
|
+
addIfStakeIxs.push(addFundsIx);
|
|
3059
3071
|
if (createWSOLTokenAccount) {
|
|
3060
|
-
|
|
3072
|
+
addIfStakeIxs.push((0, spl_token_1.createCloseAccountInstruction)(tokenAccount, this.wallet.publicKey, this.wallet.publicKey, []));
|
|
3061
3073
|
}
|
|
3074
|
+
const tx = await this.buildTransaction(addIfStakeIxs);
|
|
3062
3075
|
const { txSig } = await this.sendTransaction(tx, additionalSigners, this.opts);
|
|
3063
3076
|
return txSig;
|
|
3064
3077
|
}
|
|
@@ -3070,7 +3083,7 @@ class DriftClient {
|
|
|
3070
3083
|
useMarketLastSlotCache: true,
|
|
3071
3084
|
writableSpotMarketIndexes: [marketIndex],
|
|
3072
3085
|
});
|
|
3073
|
-
const
|
|
3086
|
+
const ix = await this.program.instruction.requestRemoveInsuranceFundStake(marketIndex, amount, {
|
|
3074
3087
|
accounts: {
|
|
3075
3088
|
state: await this.getStatePublicKey(),
|
|
3076
3089
|
spotMarket: spotMarketAccount.pubkey,
|
|
@@ -3081,6 +3094,7 @@ class DriftClient {
|
|
|
3081
3094
|
},
|
|
3082
3095
|
remainingAccounts,
|
|
3083
3096
|
});
|
|
3097
|
+
const tx = await this.buildTransaction(ix);
|
|
3084
3098
|
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
3085
3099
|
return txSig;
|
|
3086
3100
|
}
|
|
@@ -3092,7 +3106,7 @@ class DriftClient {
|
|
|
3092
3106
|
useMarketLastSlotCache: true,
|
|
3093
3107
|
writableSpotMarketIndexes: [marketIndex],
|
|
3094
3108
|
});
|
|
3095
|
-
const
|
|
3109
|
+
const ix = await this.program.instruction.cancelRequestRemoveInsuranceFundStake(marketIndex, {
|
|
3096
3110
|
accounts: {
|
|
3097
3111
|
state: await this.getStatePublicKey(),
|
|
3098
3112
|
spotMarket: spotMarketAccount.pubkey,
|
|
@@ -3103,11 +3117,12 @@ class DriftClient {
|
|
|
3103
3117
|
},
|
|
3104
3118
|
remainingAccounts,
|
|
3105
3119
|
});
|
|
3120
|
+
const tx = await this.buildTransaction(ix);
|
|
3106
3121
|
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
3107
3122
|
return txSig;
|
|
3108
3123
|
}
|
|
3109
3124
|
async removeInsuranceFundStake(marketIndex, collateralAccountPublicKey) {
|
|
3110
|
-
const
|
|
3125
|
+
const removeIfStakeIxs = [];
|
|
3111
3126
|
const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
|
|
3112
3127
|
const ifStakeAccountPublicKey = (0, pda_1.getInsuranceFundStakeAccountPublicKey)(this.program.programId, this.wallet.publicKey, marketIndex);
|
|
3113
3128
|
const additionalSigners = [];
|
|
@@ -3118,7 +3133,7 @@ class DriftClient {
|
|
|
3118
3133
|
const { ixs, pubkey } = await this.getWrappedSolAccountCreationIxs(numericConstants_1.ZERO, true);
|
|
3119
3134
|
tokenAccount = pubkey;
|
|
3120
3135
|
ixs.forEach((ix) => {
|
|
3121
|
-
|
|
3136
|
+
removeIfStakeIxs.push(ix);
|
|
3122
3137
|
});
|
|
3123
3138
|
}
|
|
3124
3139
|
else {
|
|
@@ -3143,11 +3158,12 @@ class DriftClient {
|
|
|
3143
3158
|
},
|
|
3144
3159
|
remainingAccounts,
|
|
3145
3160
|
});
|
|
3146
|
-
|
|
3161
|
+
removeIfStakeIxs.push(removeStakeIx);
|
|
3147
3162
|
// Close the wrapped sol account at the end of the transaction
|
|
3148
3163
|
if (createWSOLTokenAccount) {
|
|
3149
|
-
|
|
3164
|
+
removeIfStakeIxs.push((0, spl_token_1.createCloseAccountInstruction)(tokenAccount, this.wallet.publicKey, this.wallet.publicKey, []));
|
|
3150
3165
|
}
|
|
3166
|
+
const tx = await this.buildTransaction(removeIfStakeIxs);
|
|
3151
3167
|
const { txSig } = await this.sendTransaction(tx, additionalSigners, this.opts);
|
|
3152
3168
|
return txSig;
|
|
3153
3169
|
}
|
|
@@ -3158,7 +3174,7 @@ class DriftClient {
|
|
|
3158
3174
|
useMarketLastSlotCache: true,
|
|
3159
3175
|
writableSpotMarketIndexes: [marketIndex],
|
|
3160
3176
|
});
|
|
3161
|
-
const
|
|
3177
|
+
const ix = await this.program.instruction.settleRevenueToInsuranceFund(marketIndex, {
|
|
3162
3178
|
accounts: {
|
|
3163
3179
|
state: await this.getStatePublicKey(),
|
|
3164
3180
|
spotMarket: spotMarketAccount.pubkey,
|
|
@@ -3169,6 +3185,7 @@ class DriftClient {
|
|
|
3169
3185
|
},
|
|
3170
3186
|
remainingAccounts,
|
|
3171
3187
|
});
|
|
3188
|
+
const tx = await this.buildTransaction(ix);
|
|
3172
3189
|
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
3173
3190
|
return txSig;
|
|
3174
3191
|
}
|
package/lib/idl/drift.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "2.
|
|
2
|
+
"version": "2.43.0",
|
|
3
3
|
"name": "drift",
|
|
4
4
|
"instructions": [
|
|
5
5
|
{
|
|
@@ -4098,6 +4098,27 @@
|
|
|
4098
4098
|
}
|
|
4099
4099
|
]
|
|
4100
4100
|
},
|
|
4101
|
+
{
|
|
4102
|
+
"name": "updateLiquidationMarginBufferRatio",
|
|
4103
|
+
"accounts": [
|
|
4104
|
+
{
|
|
4105
|
+
"name": "admin",
|
|
4106
|
+
"isMut": false,
|
|
4107
|
+
"isSigner": true
|
|
4108
|
+
},
|
|
4109
|
+
{
|
|
4110
|
+
"name": "state",
|
|
4111
|
+
"isMut": true,
|
|
4112
|
+
"isSigner": false
|
|
4113
|
+
}
|
|
4114
|
+
],
|
|
4115
|
+
"args": [
|
|
4116
|
+
{
|
|
4117
|
+
"name": "liquidationMarginBufferRatio",
|
|
4118
|
+
"type": "u32"
|
|
4119
|
+
}
|
|
4120
|
+
]
|
|
4121
|
+
},
|
|
4101
4122
|
{
|
|
4102
4123
|
"name": "updateOracleGuardRails",
|
|
4103
4124
|
"accounts": [
|
|
@@ -65,6 +65,9 @@ class JupiterClient {
|
|
|
65
65
|
* @param slippageBps the slippage tolerance in basis points
|
|
66
66
|
*/
|
|
67
67
|
async getSwap({ quote, userPublicKey, slippageBps = 50, }) {
|
|
68
|
+
if (!quote) {
|
|
69
|
+
throw new Error('Jupiter swap quote not provided. Please try again.');
|
|
70
|
+
}
|
|
68
71
|
const resp = await (await (0, node_fetch_1.default)(`${this.url}/v6/swap`, {
|
|
69
72
|
method: 'POST',
|
|
70
73
|
headers: {
|
|
@@ -77,8 +80,13 @@ class JupiterClient {
|
|
|
77
80
|
}),
|
|
78
81
|
})).json();
|
|
79
82
|
const { swapTransaction } = resp;
|
|
80
|
-
|
|
81
|
-
|
|
83
|
+
try {
|
|
84
|
+
const swapTransactionBuf = Buffer.from(swapTransaction, 'base64');
|
|
85
|
+
return web3_js_1.VersionedTransaction.deserialize(swapTransactionBuf);
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
throw new Error('Something went wrong with creating the Jupiter swap transaction. Please try again.');
|
|
89
|
+
}
|
|
82
90
|
}
|
|
83
91
|
/**
|
|
84
92
|
* ** @deprecated - use getSwap
|
package/lib/math/amm.js
CHANGED
|
@@ -410,7 +410,8 @@ function calculateSpreadReserves(amm, oraclePriceData, now) {
|
|
|
410
410
|
quoteAssetReserve: amm.quoteAssetReserve,
|
|
411
411
|
};
|
|
412
412
|
}
|
|
413
|
-
const
|
|
413
|
+
const spreadFraction = anchor_1.BN.max(new anchor_1.BN(spread / 2), numericConstants_1.ONE);
|
|
414
|
+
const quoteAssetReserveDelta = amm.quoteAssetReserve.div(numericConstants_1.BID_ASK_SPREAD_PRECISION.div(spreadFraction));
|
|
414
415
|
let quoteAssetReserve;
|
|
415
416
|
if ((0, types_1.isVariant)(direction, 'long')) {
|
|
416
417
|
quoteAssetReserve = amm.quoteAssetReserve.add(quoteAssetReserveDelta);
|
package/lib/math/trade.js
CHANGED
|
@@ -415,14 +415,12 @@ function calculateEstimatedPerpEntryPrice(assetType, amount, direction, market,
|
|
|
415
415
|
limitOrder = limitOrders.next().value;
|
|
416
416
|
}
|
|
417
417
|
}
|
|
418
|
-
const entryPrice =
|
|
419
|
-
.mul(numericConstants_1.BASE_PRECISION)
|
|
420
|
-
.
|
|
421
|
-
const priceImpact =
|
|
422
|
-
.sub(bestPrice)
|
|
423
|
-
|
|
424
|
-
.div(bestPrice)
|
|
425
|
-
.abs();
|
|
418
|
+
const entryPrice = cumulativeBaseFilled && cumulativeBaseFilled.gt(numericConstants_1.ZERO)
|
|
419
|
+
? cumulativeQuoteFilled.mul(numericConstants_1.BASE_PRECISION).div(cumulativeBaseFilled)
|
|
420
|
+
: numericConstants_1.ZERO;
|
|
421
|
+
const priceImpact = bestPrice && bestPrice.gt(numericConstants_1.ZERO)
|
|
422
|
+
? entryPrice.sub(bestPrice).mul(numericConstants_1.PRICE_PRECISION).div(bestPrice).abs()
|
|
423
|
+
: numericConstants_1.ZERO;
|
|
426
424
|
return {
|
|
427
425
|
entryPrice,
|
|
428
426
|
priceImpact,
|
|
@@ -551,14 +549,12 @@ function calculateEstimatedSpotEntryPrice(assetType, amount, direction, market,
|
|
|
551
549
|
}
|
|
552
550
|
}
|
|
553
551
|
}
|
|
554
|
-
const entryPrice =
|
|
555
|
-
.mul(basePrecision)
|
|
556
|
-
.
|
|
557
|
-
const priceImpact =
|
|
558
|
-
.sub(bestPrice)
|
|
559
|
-
|
|
560
|
-
.div(bestPrice)
|
|
561
|
-
.abs();
|
|
552
|
+
const entryPrice = cumulativeBaseFilled && cumulativeBaseFilled.gt(numericConstants_1.ZERO)
|
|
553
|
+
? cumulativeQuoteFilled.mul(basePrecision).div(cumulativeBaseFilled)
|
|
554
|
+
: numericConstants_1.ZERO;
|
|
555
|
+
const priceImpact = bestPrice && bestPrice.gt(numericConstants_1.ZERO)
|
|
556
|
+
? entryPrice.sub(bestPrice).mul(numericConstants_1.PRICE_PRECISION).div(bestPrice).abs()
|
|
557
|
+
: numericConstants_1.ZERO;
|
|
562
558
|
return {
|
|
563
559
|
entryPrice,
|
|
564
560
|
priceImpact,
|
|
@@ -609,14 +605,12 @@ function calculateEstimatedEntryPriceWithL2(assetType, amount, direction, basePr
|
|
|
609
605
|
nextLevel = levels.shift();
|
|
610
606
|
}
|
|
611
607
|
}
|
|
612
|
-
const entryPrice =
|
|
613
|
-
.mul(basePrecision)
|
|
614
|
-
.
|
|
615
|
-
const priceImpact =
|
|
616
|
-
.sub(bestPrice)
|
|
617
|
-
|
|
618
|
-
.div(bestPrice)
|
|
619
|
-
.abs();
|
|
608
|
+
const entryPrice = cumulativeBaseFilled && cumulativeBaseFilled.gt(numericConstants_1.ZERO)
|
|
609
|
+
? cumulativeQuoteFilled.mul(basePrecision).div(cumulativeBaseFilled)
|
|
610
|
+
: numericConstants_1.ZERO;
|
|
611
|
+
const priceImpact = bestPrice && bestPrice.gt(numericConstants_1.ZERO)
|
|
612
|
+
? entryPrice.sub(bestPrice).mul(numericConstants_1.PRICE_PRECISION).div(bestPrice).abs()
|
|
613
|
+
: numericConstants_1.ZERO;
|
|
620
614
|
return {
|
|
621
615
|
entryPrice,
|
|
622
616
|
priceImpact,
|
|
@@ -20,7 +20,12 @@ class FastSingleTxSender extends baseTxSender_1.BaseTxSender {
|
|
|
20
20
|
}
|
|
21
21
|
startBlockhashRefreshLoop() {
|
|
22
22
|
setInterval(async () => {
|
|
23
|
-
|
|
23
|
+
try {
|
|
24
|
+
this.recentBlockhash = (await this.connection.getLatestBlockhash(this.opts)).blockhash;
|
|
25
|
+
}
|
|
26
|
+
catch (e) {
|
|
27
|
+
console.error('Error in startBlockhashRefreshLoop: ', e);
|
|
28
|
+
}
|
|
24
29
|
}, this.blockhashRefreshInterval);
|
|
25
30
|
}
|
|
26
31
|
async prepareTx(tx, additionalSigners, opts) {
|
package/lib/user.js
CHANGED
|
@@ -1677,14 +1677,13 @@ class User {
|
|
|
1677
1677
|
withdrawLimit = _1.BN.max(withdrawLimit, userDepositAmount);
|
|
1678
1678
|
}
|
|
1679
1679
|
const assetWeight = (0, spotBalance_1.calculateAssetWeight)(userDepositAmount, oracleData.price, spotMarket, 'Initial');
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
.mul(precisionIncrease);
|
|
1680
|
+
let amountWithdrawable;
|
|
1681
|
+
if (assetWeight.eq(numericConstants_1.ZERO)) {
|
|
1682
|
+
amountWithdrawable = userDepositAmount;
|
|
1683
|
+
}
|
|
1684
|
+
else {
|
|
1685
|
+
amountWithdrawable = (0, _1.divCeil)((0, _1.divCeil)(freeCollateral.mul(numericConstants_1.MARGIN_PRECISION), assetWeight).mul(numericConstants_1.PRICE_PRECISION), oracleData.price).mul(precisionIncrease);
|
|
1686
|
+
}
|
|
1688
1687
|
const maxWithdrawValue = _1.BN.min(_1.BN.min(amountWithdrawable, userDepositAmount), withdrawLimit.abs());
|
|
1689
1688
|
if (reduceOnly) {
|
|
1690
1689
|
return _1.BN.max(maxWithdrawValue, numericConstants_1.ZERO);
|
package/package.json
CHANGED
|
@@ -14,6 +14,8 @@ export class WebSocketAccountSubscriber<T> implements AccountSubscriber<T> {
|
|
|
14
14
|
onChange: (data: T) => void;
|
|
15
15
|
listenerId?: number;
|
|
16
16
|
resubTimeoutMs?: number;
|
|
17
|
+
isUnsubscribing = false;
|
|
18
|
+
|
|
17
19
|
timeoutId?: NodeJS.Timeout;
|
|
18
20
|
|
|
19
21
|
receivingData: boolean;
|
|
@@ -34,7 +36,7 @@ export class WebSocketAccountSubscriber<T> implements AccountSubscriber<T> {
|
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
async subscribe(onChange: (data: T) => void): Promise<void> {
|
|
37
|
-
if (this.listenerId) {
|
|
39
|
+
if (this.listenerId || this.isUnsubscribing) {
|
|
38
40
|
return;
|
|
39
41
|
}
|
|
40
42
|
|
|
@@ -80,6 +82,11 @@ export class WebSocketAccountSubscriber<T> implements AccountSubscriber<T> {
|
|
|
80
82
|
throw new Error('onChange callback function must be set');
|
|
81
83
|
}
|
|
82
84
|
this.timeoutId = setTimeout(async () => {
|
|
85
|
+
if (this.isUnsubscribing) {
|
|
86
|
+
// If we are in the process of unsubscribing, do not attempt to resubscribe
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
|
|
83
90
|
if (this.receivingData) {
|
|
84
91
|
console.log(
|
|
85
92
|
`No ws data from ${this.accountName} in ${this.resubTimeoutMs}ms, resubscribing`
|
|
@@ -154,13 +161,20 @@ export class WebSocketAccountSubscriber<T> implements AccountSubscriber<T> {
|
|
|
154
161
|
}
|
|
155
162
|
|
|
156
163
|
unsubscribe(): Promise<void> {
|
|
164
|
+
this.isUnsubscribing = true;
|
|
165
|
+
clearTimeout(this.timeoutId);
|
|
166
|
+
this.timeoutId = undefined;
|
|
167
|
+
|
|
157
168
|
if (this.listenerId) {
|
|
158
|
-
const promise =
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
169
|
+
const promise = this.program.provider.connection
|
|
170
|
+
.removeAccountChangeListener(this.listenerId)
|
|
171
|
+
.then(() => {
|
|
172
|
+
this.listenerId = undefined;
|
|
173
|
+
this.isUnsubscribing = false;
|
|
174
|
+
});
|
|
163
175
|
return promise;
|
|
176
|
+
} else {
|
|
177
|
+
this.isUnsubscribing = false;
|
|
164
178
|
}
|
|
165
179
|
}
|
|
166
180
|
}
|