@drift-labs/sdk 2.96.0-beta.7 → 2.96.0-beta.9
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/constants/perpMarkets.js +10 -0
- package/lib/driftClient.d.ts +9 -1
- package/lib/driftClient.js +25 -6
- package/lib/math/margin.d.ts +16 -1
- package/lib/math/margin.js +67 -1
- package/lib/user.d.ts +4 -1
- package/lib/user.js +9 -2
- package/package.json +1 -1
- package/src/constants/perpMarkets.ts +10 -0
- package/src/driftClient.ts +80 -11
- package/src/math/margin.ts +137 -1
- package/src/user.ts +35 -2
- package/tests/ci/idl.ts +12 -3
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.96.0-beta.
|
|
1
|
+
2.96.0-beta.9
|
|
@@ -778,6 +778,16 @@ exports.MainnetPerpMarkets = [
|
|
|
778
778
|
oracleSource: __1.OracleSource.PYTH_PULL,
|
|
779
779
|
pythFeedId: '0x8963217838ab4cf5cadc172203c1f0b763fbaa45f346d8ee50ba994bbcac3026',
|
|
780
780
|
},
|
|
781
|
+
{
|
|
782
|
+
fullName: 'LANDO-F1-SGP-WIN-BET',
|
|
783
|
+
category: ['Prediction', 'Sports'],
|
|
784
|
+
symbol: 'LANDO-F1-SGP-WIN-BET',
|
|
785
|
+
baseAssetSymbol: 'LANDO-F1-SGP-WIN',
|
|
786
|
+
marketIndex: 43,
|
|
787
|
+
oracle: new web3_js_1.PublicKey('DpJz7rjTJLxxnuqrqZTUjMWtnaMFAEfZUv5ATdb9HTh1'),
|
|
788
|
+
launchTs: 1726646453000,
|
|
789
|
+
oracleSource: __1.OracleSource.Prelaunch,
|
|
790
|
+
},
|
|
781
791
|
];
|
|
782
792
|
exports.PerpMarkets = {
|
|
783
793
|
devnet: exports.DevnetPerpMarkets,
|
package/lib/driftClient.d.ts
CHANGED
|
@@ -239,6 +239,7 @@ export declare class DriftClient {
|
|
|
239
239
|
*/
|
|
240
240
|
getAssociatedTokenAccount(marketIndex: number, useNative?: boolean, tokenProgram?: anchor.web3.PublicKey): Promise<PublicKey>;
|
|
241
241
|
createAssociatedTokenAccountIdempotentInstruction(account: PublicKey, payer: PublicKey, owner: PublicKey, mint: PublicKey, tokenProgram?: anchor.web3.PublicKey): TransactionInstruction;
|
|
242
|
+
getDepositTxnIx(amount: BN, marketIndex: number, associatedTokenAccount: PublicKey, subAccountId?: number, reduceOnly?: boolean): Promise<TransactionInstruction[]>;
|
|
242
243
|
createDepositTxn(amount: BN, marketIndex: number, associatedTokenAccount: PublicKey, subAccountId?: number, reduceOnly?: boolean, txParams?: TxParams): Promise<VersionedTransaction | Transaction>;
|
|
243
244
|
/**
|
|
244
245
|
* Deposit funds into the given spot market
|
|
@@ -261,6 +262,10 @@ export declare class DriftClient {
|
|
|
261
262
|
getTokenProgramForSpotMarket(spotMarketAccount: SpotMarketAccount): PublicKey;
|
|
262
263
|
addTokenMintToRemainingAccounts(spotMarketAccount: SpotMarketAccount, remainingAccounts: AccountMeta[]): void;
|
|
263
264
|
getAssociatedTokenAccountCreationIx(tokenMintAddress: PublicKey, associatedTokenAddress: PublicKey, tokenProgram: PublicKey): anchor.web3.TransactionInstruction;
|
|
265
|
+
createInitializeUserAccountAndDepositCollateralIxs(amount: BN, userTokenAccount: PublicKey, marketIndex?: number, subAccountId?: number, name?: string, fromSubAccountId?: number, referrerInfo?: ReferrerInfo, donateAmount?: BN, customMaxMarginRatio?: number): Promise<{
|
|
266
|
+
ixs: TransactionInstruction[];
|
|
267
|
+
userAccountPublicKey: PublicKey;
|
|
268
|
+
}>;
|
|
264
269
|
createInitializeUserAccountAndDepositCollateral(amount: BN, userTokenAccount: PublicKey, marketIndex?: number, subAccountId?: number, name?: string, fromSubAccountId?: number, referrerInfo?: ReferrerInfo, donateAmount?: BN, txParams?: TxParams, customMaxMarginRatio?: number): Promise<[Transaction | VersionedTransaction, PublicKey]>;
|
|
265
270
|
/**
|
|
266
271
|
* Creates the User account for a user, and deposits some initial collateral
|
|
@@ -340,7 +345,10 @@ export declare class DriftClient {
|
|
|
340
345
|
signedSettlePnlTx?: Transaction;
|
|
341
346
|
}>;
|
|
342
347
|
placePerpOrder(orderParams: OptionalOrderParams, txParams?: TxParams, subAccountId?: number): Promise<TransactionSignature>;
|
|
343
|
-
getPlacePerpOrderIx(orderParams: OptionalOrderParams, subAccountId?: number
|
|
348
|
+
getPlacePerpOrderIx(orderParams: OptionalOrderParams, subAccountId?: number, depositToTradeArgs?: {
|
|
349
|
+
isMakingNewAccount: boolean;
|
|
350
|
+
depositMarketIndex: number;
|
|
351
|
+
}): Promise<TransactionInstruction>;
|
|
344
352
|
updateAMMs(marketIndexes: number[], txParams?: TxParams): Promise<TransactionSignature>;
|
|
345
353
|
getUpdateAMMsIx(marketIndexes: number[]): Promise<TransactionInstruction>;
|
|
346
354
|
settleExpiredMarket(marketIndex: number, txParams?: TxParams): Promise<TransactionSignature>;
|
package/lib/driftClient.js
CHANGED
|
@@ -1118,7 +1118,7 @@ class DriftClient {
|
|
|
1118
1118
|
data: Buffer.from([0x1]),
|
|
1119
1119
|
});
|
|
1120
1120
|
}
|
|
1121
|
-
async
|
|
1121
|
+
async getDepositTxnIx(amount, marketIndex, associatedTokenAccount, subAccountId, reduceOnly = false) {
|
|
1122
1122
|
const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
|
|
1123
1123
|
const isSolMarket = spotMarketAccount.mint.equals(spotMarkets_1.WRAPPED_SOL_MINT);
|
|
1124
1124
|
const signerAuthority = this.wallet.publicKey;
|
|
@@ -1135,6 +1135,10 @@ class DriftClient {
|
|
|
1135
1135
|
if (createWSOLTokenAccount) {
|
|
1136
1136
|
instructions.push((0, spl_token_1.createCloseAccountInstruction)(associatedTokenAccount, signerAuthority, signerAuthority, []));
|
|
1137
1137
|
}
|
|
1138
|
+
return instructions;
|
|
1139
|
+
}
|
|
1140
|
+
async createDepositTxn(amount, marketIndex, associatedTokenAccount, subAccountId, reduceOnly = false, txParams) {
|
|
1141
|
+
const instructions = await this.getDepositTxnIx(amount, marketIndex, associatedTokenAccount, subAccountId, reduceOnly);
|
|
1138
1142
|
txParams = { ...(txParams !== null && txParams !== void 0 ? txParams : this.txParams), computeUnits: 600000 };
|
|
1139
1143
|
const tx = await this.buildTransaction(instructions, txParams);
|
|
1140
1144
|
return tx;
|
|
@@ -1242,7 +1246,7 @@ class DriftClient {
|
|
|
1242
1246
|
getAssociatedTokenAccountCreationIx(tokenMintAddress, associatedTokenAddress, tokenProgram) {
|
|
1243
1247
|
return (0, spl_token_1.createAssociatedTokenAccountInstruction)(this.wallet.publicKey, associatedTokenAddress, this.wallet.publicKey, tokenMintAddress, tokenProgram);
|
|
1244
1248
|
}
|
|
1245
|
-
async
|
|
1249
|
+
async createInitializeUserAccountAndDepositCollateralIxs(amount, userTokenAccount, marketIndex = 0, subAccountId = 0, name, fromSubAccountId, referrerInfo, donateAmount, customMaxMarginRatio) {
|
|
1246
1250
|
const ixs = [];
|
|
1247
1251
|
const [userAccountPublicKey, initializeUserAccountIx] = await this.getInitializeUserInstructions(subAccountId, name, referrerInfo);
|
|
1248
1252
|
const spotMarket = this.getSpotMarketAccount(marketIndex);
|
|
@@ -1288,6 +1292,13 @@ class DriftClient {
|
|
|
1288
1292
|
if (createWSOLTokenAccount) {
|
|
1289
1293
|
ixs.push((0, spl_token_1.createCloseAccountInstruction)(wsolTokenAccount, authority, authority, []));
|
|
1290
1294
|
}
|
|
1295
|
+
return {
|
|
1296
|
+
ixs,
|
|
1297
|
+
userAccountPublicKey,
|
|
1298
|
+
};
|
|
1299
|
+
}
|
|
1300
|
+
async createInitializeUserAccountAndDepositCollateral(amount, userTokenAccount, marketIndex = 0, subAccountId = 0, name, fromSubAccountId, referrerInfo, donateAmount, txParams, customMaxMarginRatio) {
|
|
1301
|
+
const { ixs, userAccountPublicKey } = await this.createInitializeUserAccountAndDepositCollateralIxs(amount, userTokenAccount, marketIndex, subAccountId, name, fromSubAccountId, referrerInfo, donateAmount, customMaxMarginRatio);
|
|
1291
1302
|
const tx = await this.buildTransaction(ixs, txParams);
|
|
1292
1303
|
return [tx, userAccountPublicKey];
|
|
1293
1304
|
}
|
|
@@ -1663,13 +1674,21 @@ class DriftClient {
|
|
|
1663
1674
|
this.perpMarketLastSlotCache.set(orderParams.marketIndex, slot);
|
|
1664
1675
|
return txSig;
|
|
1665
1676
|
}
|
|
1666
|
-
async getPlacePerpOrderIx(orderParams, subAccountId) {
|
|
1677
|
+
async getPlacePerpOrderIx(orderParams, subAccountId, depositToTradeArgs) {
|
|
1667
1678
|
orderParams = (0, orderParams_1.getOrderParams)(orderParams, { marketType: types_1.MarketType.PERP });
|
|
1668
|
-
const
|
|
1679
|
+
const isDepositToTradeTx = depositToTradeArgs !== undefined;
|
|
1680
|
+
const user = isDepositToTradeTx
|
|
1681
|
+
? (0, pda_1.getUserAccountPublicKeySync)(this.program.programId, this.authority, subAccountId)
|
|
1682
|
+
: await this.getUserAccountPublicKey(subAccountId);
|
|
1669
1683
|
const remainingAccounts = this.getRemainingAccounts({
|
|
1670
|
-
userAccounts:
|
|
1671
|
-
|
|
1684
|
+
userAccounts: (depositToTradeArgs === null || depositToTradeArgs === void 0 ? void 0 : depositToTradeArgs.isMakingNewAccount)
|
|
1685
|
+
? []
|
|
1686
|
+
: [this.getUserAccount(subAccountId)],
|
|
1687
|
+
useMarketLastSlotCache: false,
|
|
1672
1688
|
readablePerpMarketIndex: orderParams.marketIndex,
|
|
1689
|
+
readableSpotMarketIndexes: isDepositToTradeTx
|
|
1690
|
+
? [depositToTradeArgs === null || depositToTradeArgs === void 0 ? void 0 : depositToTradeArgs.depositMarketIndex]
|
|
1691
|
+
: undefined,
|
|
1673
1692
|
});
|
|
1674
1693
|
return await this.program.instruction.placePerpOrder(orderParams, {
|
|
1675
1694
|
accounts: {
|
package/lib/math/margin.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/// <reference types="bn.js" />
|
|
2
2
|
import { BN } from '@coral-xyz/anchor';
|
|
3
3
|
import { OraclePriceData } from '../oracles/types';
|
|
4
|
-
import { PerpMarketAccount, PerpPosition } from '..';
|
|
4
|
+
import { DriftClient, PerpMarketAccount, PerpPosition } from '..';
|
|
5
5
|
export declare function calculateSizePremiumLiabilityWeight(size: BN, // AMM_RESERVE_PRECISION
|
|
6
6
|
imfFactor: BN, liabilityWeight: BN, precision: BN): BN;
|
|
7
7
|
export declare function calculateSizeDiscountAssetWeight(size: BN, // AMM_RESERVE_PRECISION
|
|
@@ -22,3 +22,18 @@ export declare function calculateWorstCasePerpLiabilityValue(perpPosition: PerpP
|
|
|
22
22
|
worstCaseLiabilityValue: BN;
|
|
23
23
|
};
|
|
24
24
|
export declare function calculatePerpLiabilityValue(baseAssetAmount: BN, oraclePrice: BN, isPredictionMarket: boolean): BN;
|
|
25
|
+
/**
|
|
26
|
+
* Calculates the margin required to open a trade, in quote amount. Only accounts for the trade size as a scalar value, does not account for the trade direction or current open positions and whether the trade would _actually_ be risk-increasing and use any extra collateral.
|
|
27
|
+
* @param targetMarketIndex
|
|
28
|
+
* @param baseSize
|
|
29
|
+
* @returns
|
|
30
|
+
*/
|
|
31
|
+
export declare function calculateMarginUSDCRequiredForTrade(driftClient: DriftClient, targetMarketIndex: number, baseSize: BN, userMaxMarginRatio?: number): BN;
|
|
32
|
+
/**
|
|
33
|
+
* Similar to calculatetMarginUSDCRequiredForTrade, but calculates how much of a given collateral is required to cover the margin requirements for a given trade. Basically does the same thing as getMarginUSDCRequiredForTrade but also accounts for asset weight of the selected collateral.
|
|
34
|
+
*
|
|
35
|
+
* Returns collateral required in the precision of the target collateral market.
|
|
36
|
+
*/
|
|
37
|
+
export declare function calculateCollateralDepositRequiredForTrade(driftClient: DriftClient, targetMarketIndex: number, baseSize: BN, collateralIndex: number, userMaxMarginRatio?: number): BN;
|
|
38
|
+
export declare function calculateCollateralValueOfDeposit(driftClient: DriftClient, collateralIndex: number, baseSize: BN): BN;
|
|
39
|
+
export declare function calculateLiquidationPrice(freeCollateral: BN, freeCollateralDelta: BN, oraclePrice: BN): BN;
|
package/lib/math/margin.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.calculatePerpLiabilityValue = exports.calculateWorstCasePerpLiabilityValue = exports.calculateWorstCaseBaseAssetAmount = exports.calculateBaseAssetValueWithOracle = exports.calculateOraclePriceForPerpMargin = exports.calculateSizeDiscountAssetWeight = exports.calculateSizePremiumLiabilityWeight = void 0;
|
|
3
|
+
exports.calculateLiquidationPrice = exports.calculateCollateralValueOfDeposit = exports.calculateCollateralDepositRequiredForTrade = exports.calculateMarginUSDCRequiredForTrade = exports.calculatePerpLiabilityValue = exports.calculateWorstCasePerpLiabilityValue = exports.calculateWorstCaseBaseAssetAmount = exports.calculateBaseAssetValueWithOracle = exports.calculateOraclePriceForPerpMargin = exports.calculateSizeDiscountAssetWeight = exports.calculateSizePremiumLiabilityWeight = void 0;
|
|
4
4
|
const utils_1 = require("./utils");
|
|
5
5
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
6
6
|
const anchor_1 = require("@coral-xyz/anchor");
|
|
7
|
+
const __1 = require("..");
|
|
7
8
|
const types_1 = require("../types");
|
|
8
9
|
const assert_1 = require("../assert/assert");
|
|
9
10
|
function calculateSizePremiumLiabilityWeight(size, // AMM_RESERVE_PRECISION
|
|
@@ -116,3 +117,68 @@ function calculatePerpLiabilityValue(baseAssetAmount, oraclePrice, isPredictionM
|
|
|
116
117
|
}
|
|
117
118
|
}
|
|
118
119
|
exports.calculatePerpLiabilityValue = calculatePerpLiabilityValue;
|
|
120
|
+
/**
|
|
121
|
+
* Calculates the margin required to open a trade, in quote amount. Only accounts for the trade size as a scalar value, does not account for the trade direction or current open positions and whether the trade would _actually_ be risk-increasing and use any extra collateral.
|
|
122
|
+
* @param targetMarketIndex
|
|
123
|
+
* @param baseSize
|
|
124
|
+
* @returns
|
|
125
|
+
*/
|
|
126
|
+
function calculateMarginUSDCRequiredForTrade(driftClient, targetMarketIndex, baseSize, userMaxMarginRatio) {
|
|
127
|
+
const targetMarket = driftClient.getPerpMarketAccount(targetMarketIndex);
|
|
128
|
+
const oracleData = driftClient.getOracleDataForPerpMarket(targetMarket.marketIndex);
|
|
129
|
+
const perpLiabilityValue = calculatePerpLiabilityValue(baseSize, oracleData.price, (0, types_1.isVariant)(targetMarket.contractType, 'prediction'));
|
|
130
|
+
const marginRequired = new anchor_1.BN((0, __1.calculateMarketMarginRatio)(targetMarket, baseSize.abs(), 'Initial', userMaxMarginRatio))
|
|
131
|
+
.mul(perpLiabilityValue)
|
|
132
|
+
.div(numericConstants_1.MARGIN_PRECISION);
|
|
133
|
+
return marginRequired;
|
|
134
|
+
}
|
|
135
|
+
exports.calculateMarginUSDCRequiredForTrade = calculateMarginUSDCRequiredForTrade;
|
|
136
|
+
/**
|
|
137
|
+
* Similar to calculatetMarginUSDCRequiredForTrade, but calculates how much of a given collateral is required to cover the margin requirements for a given trade. Basically does the same thing as getMarginUSDCRequiredForTrade but also accounts for asset weight of the selected collateral.
|
|
138
|
+
*
|
|
139
|
+
* Returns collateral required in the precision of the target collateral market.
|
|
140
|
+
*/
|
|
141
|
+
function calculateCollateralDepositRequiredForTrade(driftClient, targetMarketIndex, baseSize, collateralIndex, userMaxMarginRatio) {
|
|
142
|
+
const marginRequiredUsdc = calculateMarginUSDCRequiredForTrade(driftClient, targetMarketIndex, baseSize, userMaxMarginRatio);
|
|
143
|
+
const collateralMarket = driftClient.getSpotMarketAccount(collateralIndex);
|
|
144
|
+
const collateralOracleData = driftClient.getOracleDataForSpotMarket(collateralIndex);
|
|
145
|
+
const scaledAssetWeight = (0, __1.calculateScaledInitialAssetWeight)(collateralMarket, collateralOracleData.price);
|
|
146
|
+
// Base amount required to deposit = (marginRequiredUsdc / priceOfAsset) / assetWeight .. (E.g. $100 required / $10000 price / 0.5 weight)
|
|
147
|
+
const baseAmountRequired = driftClient
|
|
148
|
+
.convertToSpotPrecision(collateralIndex, marginRequiredUsdc)
|
|
149
|
+
.mul(numericConstants_1.PRICE_PRECISION) // adjust for division by oracle price
|
|
150
|
+
.mul(numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION) // adjust for division by scaled asset weight
|
|
151
|
+
.div(collateralOracleData.price)
|
|
152
|
+
.div(scaledAssetWeight)
|
|
153
|
+
.div(numericConstants_1.QUOTE_PRECISION); // adjust for marginRequiredUsdc value's QUOTE_PRECISION
|
|
154
|
+
// TODO : Round by step size?
|
|
155
|
+
return baseAmountRequired;
|
|
156
|
+
}
|
|
157
|
+
exports.calculateCollateralDepositRequiredForTrade = calculateCollateralDepositRequiredForTrade;
|
|
158
|
+
function calculateCollateralValueOfDeposit(driftClient, collateralIndex, baseSize) {
|
|
159
|
+
const collateralMarket = driftClient.getSpotMarketAccount(collateralIndex);
|
|
160
|
+
const collateralOracleData = driftClient.getOracleDataForSpotMarket(collateralIndex);
|
|
161
|
+
const scaledAssetWeight = (0, __1.calculateScaledInitialAssetWeight)(collateralMarket, collateralOracleData.price);
|
|
162
|
+
// CollateralBaseValue = oracle price * collateral base amount (and shift to QUOTE_PRECISION)
|
|
163
|
+
const collateralBaseValue = collateralOracleData.price
|
|
164
|
+
.mul(baseSize)
|
|
165
|
+
.mul(numericConstants_1.QUOTE_PRECISION)
|
|
166
|
+
.div(numericConstants_1.PRICE_PRECISION)
|
|
167
|
+
.div(new anchor_1.BN(10).pow(new anchor_1.BN(collateralMarket.decimals)));
|
|
168
|
+
const depositCollateralValue = collateralBaseValue
|
|
169
|
+
.mul(scaledAssetWeight)
|
|
170
|
+
.div(numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION);
|
|
171
|
+
return depositCollateralValue;
|
|
172
|
+
}
|
|
173
|
+
exports.calculateCollateralValueOfDeposit = calculateCollateralValueOfDeposit;
|
|
174
|
+
function calculateLiquidationPrice(freeCollateral, freeCollateralDelta, oraclePrice) {
|
|
175
|
+
const liqPriceDelta = freeCollateral
|
|
176
|
+
.mul(numericConstants_1.QUOTE_PRECISION)
|
|
177
|
+
.div(freeCollateralDelta);
|
|
178
|
+
const liqPrice = oraclePrice.sub(liqPriceDelta);
|
|
179
|
+
if (liqPrice.lt(numericConstants_1.ZERO)) {
|
|
180
|
+
return new anchor_1.BN(-1);
|
|
181
|
+
}
|
|
182
|
+
return liqPrice;
|
|
183
|
+
}
|
|
184
|
+
exports.calculateLiquidationPrice = calculateLiquidationPrice;
|
package/lib/user.d.ts
CHANGED
|
@@ -265,9 +265,10 @@ export declare class User {
|
|
|
265
265
|
* @param estimatedEntryPrice
|
|
266
266
|
* @param marginCategory // allow Initial to be passed in if we are trying to calculate price for DLP de-risking
|
|
267
267
|
* @param includeOpenOrders
|
|
268
|
+
* @param offsetCollateral // allows calculating the liquidation price after this offset collateral is added to the user's account (e.g. : what will the liquidation price be for this position AFTER I deposit $x worth of collateral)
|
|
268
269
|
* @returns Precision : PRICE_PRECISION
|
|
269
270
|
*/
|
|
270
|
-
liquidationPrice(marketIndex: number, positionBaseSizeChange?: BN, estimatedEntryPrice?: BN, marginCategory?: MarginCategory, includeOpenOrders?: boolean): BN;
|
|
271
|
+
liquidationPrice(marketIndex: number, positionBaseSizeChange?: BN, estimatedEntryPrice?: BN, marginCategory?: MarginCategory, includeOpenOrders?: boolean, offsetCollateral?: BN): BN;
|
|
271
272
|
calculateEntriesEffectOnFreeCollateral(market: PerpMarketAccount, oraclePrice: BN, perpPosition: PerpPosition, positionBaseSizeChange: BN, estimatedEntryPrice: BN, includeOpenOrders: boolean): BN;
|
|
272
273
|
calculateFreeCollateralDeltaForPerp(market: PerpMarketAccount, perpPosition: PerpPosition, positionBaseSizeChange: BN, oraclePrice: BN, marginCategory?: MarginCategory, includeOpenOrders?: boolean): BN | undefined;
|
|
273
274
|
calculateFreeCollateralDeltaForSpot(market: SpotMarketAccount, signedTokenAmount: BN, marginCategory?: MarginCategory): BN;
|
|
@@ -278,6 +279,8 @@ export declare class User {
|
|
|
278
279
|
* @returns : Precision PRICE_PRECISION
|
|
279
280
|
*/
|
|
280
281
|
liquidationPriceAfterClose(positionMarketIndex: number, closeQuoteAmount: BN, estimatedEntryPrice?: BN): BN;
|
|
282
|
+
getMarginUSDCRequiredForTrade(targetMarketIndex: number, baseSize: BN): BN;
|
|
283
|
+
getCollateralDepositRequiredForTrade(targetMarketIndex: number, baseSize: BN, collateralIndex: number): BN;
|
|
281
284
|
/**
|
|
282
285
|
* Get the maximum trade size for a given market, taking into account the user's current leverage, positions, collateral, etc.
|
|
283
286
|
*
|
package/lib/user.js
CHANGED
|
@@ -1202,12 +1202,13 @@ class User {
|
|
|
1202
1202
|
* @param estimatedEntryPrice
|
|
1203
1203
|
* @param marginCategory // allow Initial to be passed in if we are trying to calculate price for DLP de-risking
|
|
1204
1204
|
* @param includeOpenOrders
|
|
1205
|
+
* @param offsetCollateral // allows calculating the liquidation price after this offset collateral is added to the user's account (e.g. : what will the liquidation price be for this position AFTER I deposit $x worth of collateral)
|
|
1205
1206
|
* @returns Precision : PRICE_PRECISION
|
|
1206
1207
|
*/
|
|
1207
|
-
liquidationPrice(marketIndex, positionBaseSizeChange = numericConstants_1.ZERO, estimatedEntryPrice = numericConstants_1.ZERO, marginCategory = 'Maintenance', includeOpenOrders = false) {
|
|
1208
|
+
liquidationPrice(marketIndex, positionBaseSizeChange = numericConstants_1.ZERO, estimatedEntryPrice = numericConstants_1.ZERO, marginCategory = 'Maintenance', includeOpenOrders = false, offsetCollateral = numericConstants_1.ZERO) {
|
|
1208
1209
|
const totalCollateral = this.getTotalCollateral(marginCategory);
|
|
1209
1210
|
const marginRequirement = this.getMarginRequirement(marginCategory, undefined, false, includeOpenOrders);
|
|
1210
|
-
let freeCollateral = _1.BN.max(numericConstants_1.ZERO, totalCollateral.sub(marginRequirement));
|
|
1211
|
+
let freeCollateral = _1.BN.max(numericConstants_1.ZERO, totalCollateral.sub(marginRequirement)).add(offsetCollateral);
|
|
1211
1212
|
const oracle = this.driftClient.getPerpMarketAccount(marketIndex).amm.oracle;
|
|
1212
1213
|
const oraclePrice = this.driftClient.getOracleDataForPerpMarket(marketIndex).price;
|
|
1213
1214
|
const market = this.driftClient.getPerpMarketAccount(marketIndex);
|
|
@@ -1367,6 +1368,12 @@ class User {
|
|
|
1367
1368
|
.neg();
|
|
1368
1369
|
return this.liquidationPrice(positionMarketIndex, closeBaseAmount, estimatedEntryPrice);
|
|
1369
1370
|
}
|
|
1371
|
+
getMarginUSDCRequiredForTrade(targetMarketIndex, baseSize) {
|
|
1372
|
+
return (0, margin_1.calculateMarginUSDCRequiredForTrade)(this.driftClient, targetMarketIndex, baseSize, this.getUserAccount().maxMarginRatio);
|
|
1373
|
+
}
|
|
1374
|
+
getCollateralDepositRequiredForTrade(targetMarketIndex, baseSize, collateralIndex) {
|
|
1375
|
+
return (0, margin_1.calculateCollateralDepositRequiredForTrade)(this.driftClient, targetMarketIndex, baseSize, collateralIndex, this.getUserAccount().maxMarginRatio);
|
|
1376
|
+
}
|
|
1370
1377
|
/**
|
|
1371
1378
|
* Get the maximum trade size for a given market, taking into account the user's current leverage, positions, collateral, etc.
|
|
1372
1379
|
*
|
package/package.json
CHANGED
|
@@ -852,6 +852,16 @@ export const MainnetPerpMarkets: PerpMarketConfig[] = [
|
|
|
852
852
|
pythFeedId:
|
|
853
853
|
'0x8963217838ab4cf5cadc172203c1f0b763fbaa45f346d8ee50ba994bbcac3026',
|
|
854
854
|
},
|
|
855
|
+
{
|
|
856
|
+
fullName: 'LANDO-F1-SGP-WIN-BET',
|
|
857
|
+
category: ['Prediction', 'Sports'],
|
|
858
|
+
symbol: 'LANDO-F1-SGP-WIN-BET',
|
|
859
|
+
baseAssetSymbol: 'LANDO-F1-SGP-WIN',
|
|
860
|
+
marketIndex: 43,
|
|
861
|
+
oracle: new PublicKey('DpJz7rjTJLxxnuqrqZTUjMWtnaMFAEfZUv5ATdb9HTh1'),
|
|
862
|
+
launchTs: 1726646453000,
|
|
863
|
+
oracleSource: OracleSource.Prelaunch,
|
|
864
|
+
},
|
|
855
865
|
];
|
|
856
866
|
|
|
857
867
|
export const PerpMarkets: { [key in DriftEnv]: PerpMarketConfig[] } = {
|
package/src/driftClient.ts
CHANGED
|
@@ -1906,14 +1906,13 @@ export class DriftClient {
|
|
|
1906
1906
|
});
|
|
1907
1907
|
}
|
|
1908
1908
|
|
|
1909
|
-
public async
|
|
1909
|
+
public async getDepositTxnIx(
|
|
1910
1910
|
amount: BN,
|
|
1911
1911
|
marketIndex: number,
|
|
1912
1912
|
associatedTokenAccount: PublicKey,
|
|
1913
1913
|
subAccountId?: number,
|
|
1914
|
-
reduceOnly = false
|
|
1915
|
-
|
|
1916
|
-
): Promise<VersionedTransaction | Transaction> {
|
|
1914
|
+
reduceOnly = false
|
|
1915
|
+
): Promise<TransactionInstruction[]> {
|
|
1917
1916
|
const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
|
|
1918
1917
|
|
|
1919
1918
|
const isSolMarket = spotMarketAccount.mint.equals(WRAPPED_SOL_MINT);
|
|
@@ -1959,6 +1958,25 @@ export class DriftClient {
|
|
|
1959
1958
|
);
|
|
1960
1959
|
}
|
|
1961
1960
|
|
|
1961
|
+
return instructions;
|
|
1962
|
+
}
|
|
1963
|
+
|
|
1964
|
+
public async createDepositTxn(
|
|
1965
|
+
amount: BN,
|
|
1966
|
+
marketIndex: number,
|
|
1967
|
+
associatedTokenAccount: PublicKey,
|
|
1968
|
+
subAccountId?: number,
|
|
1969
|
+
reduceOnly = false,
|
|
1970
|
+
txParams?: TxParams
|
|
1971
|
+
): Promise<VersionedTransaction | Transaction> {
|
|
1972
|
+
const instructions = await this.getDepositTxnIx(
|
|
1973
|
+
amount,
|
|
1974
|
+
marketIndex,
|
|
1975
|
+
associatedTokenAccount,
|
|
1976
|
+
subAccountId,
|
|
1977
|
+
reduceOnly
|
|
1978
|
+
);
|
|
1979
|
+
|
|
1962
1980
|
txParams = { ...(txParams ?? this.txParams), computeUnits: 600_000 };
|
|
1963
1981
|
|
|
1964
1982
|
const tx = await this.buildTransaction(instructions, txParams);
|
|
@@ -2151,7 +2169,7 @@ export class DriftClient {
|
|
|
2151
2169
|
);
|
|
2152
2170
|
}
|
|
2153
2171
|
|
|
2154
|
-
public async
|
|
2172
|
+
public async createInitializeUserAccountAndDepositCollateralIxs(
|
|
2155
2173
|
amount: BN,
|
|
2156
2174
|
userTokenAccount: PublicKey,
|
|
2157
2175
|
marketIndex = 0,
|
|
@@ -2160,9 +2178,11 @@ export class DriftClient {
|
|
|
2160
2178
|
fromSubAccountId?: number,
|
|
2161
2179
|
referrerInfo?: ReferrerInfo,
|
|
2162
2180
|
donateAmount?: BN,
|
|
2163
|
-
txParams?: TxParams,
|
|
2164
2181
|
customMaxMarginRatio?: number
|
|
2165
|
-
): Promise<
|
|
2182
|
+
): Promise<{
|
|
2183
|
+
ixs: TransactionInstruction[];
|
|
2184
|
+
userAccountPublicKey: PublicKey;
|
|
2185
|
+
}> {
|
|
2166
2186
|
const ixs = [];
|
|
2167
2187
|
|
|
2168
2188
|
const [userAccountPublicKey, initializeUserAccountIx] =
|
|
@@ -2263,6 +2283,37 @@ export class DriftClient {
|
|
|
2263
2283
|
);
|
|
2264
2284
|
}
|
|
2265
2285
|
|
|
2286
|
+
return {
|
|
2287
|
+
ixs,
|
|
2288
|
+
userAccountPublicKey,
|
|
2289
|
+
};
|
|
2290
|
+
}
|
|
2291
|
+
|
|
2292
|
+
public async createInitializeUserAccountAndDepositCollateral(
|
|
2293
|
+
amount: BN,
|
|
2294
|
+
userTokenAccount: PublicKey,
|
|
2295
|
+
marketIndex = 0,
|
|
2296
|
+
subAccountId = 0,
|
|
2297
|
+
name?: string,
|
|
2298
|
+
fromSubAccountId?: number,
|
|
2299
|
+
referrerInfo?: ReferrerInfo,
|
|
2300
|
+
donateAmount?: BN,
|
|
2301
|
+
txParams?: TxParams,
|
|
2302
|
+
customMaxMarginRatio?: number
|
|
2303
|
+
): Promise<[Transaction | VersionedTransaction, PublicKey]> {
|
|
2304
|
+
const { ixs, userAccountPublicKey } =
|
|
2305
|
+
await this.createInitializeUserAccountAndDepositCollateralIxs(
|
|
2306
|
+
amount,
|
|
2307
|
+
userTokenAccount,
|
|
2308
|
+
marketIndex,
|
|
2309
|
+
subAccountId,
|
|
2310
|
+
name,
|
|
2311
|
+
fromSubAccountId,
|
|
2312
|
+
referrerInfo,
|
|
2313
|
+
donateAmount,
|
|
2314
|
+
customMaxMarginRatio
|
|
2315
|
+
);
|
|
2316
|
+
|
|
2266
2317
|
const tx = await this.buildTransaction(ixs, txParams);
|
|
2267
2318
|
|
|
2268
2319
|
return [tx, userAccountPublicKey];
|
|
@@ -3129,15 +3180,33 @@ export class DriftClient {
|
|
|
3129
3180
|
|
|
3130
3181
|
public async getPlacePerpOrderIx(
|
|
3131
3182
|
orderParams: OptionalOrderParams,
|
|
3132
|
-
subAccountId?: number
|
|
3183
|
+
subAccountId?: number,
|
|
3184
|
+
depositToTradeArgs?: {
|
|
3185
|
+
isMakingNewAccount: boolean;
|
|
3186
|
+
depositMarketIndex: number;
|
|
3187
|
+
}
|
|
3133
3188
|
): Promise<TransactionInstruction> {
|
|
3134
3189
|
orderParams = getOrderParams(orderParams, { marketType: MarketType.PERP });
|
|
3135
|
-
|
|
3190
|
+
|
|
3191
|
+
const isDepositToTradeTx = depositToTradeArgs !== undefined;
|
|
3192
|
+
|
|
3193
|
+
const user = isDepositToTradeTx
|
|
3194
|
+
? getUserAccountPublicKeySync(
|
|
3195
|
+
this.program.programId,
|
|
3196
|
+
this.authority,
|
|
3197
|
+
subAccountId
|
|
3198
|
+
)
|
|
3199
|
+
: await this.getUserAccountPublicKey(subAccountId);
|
|
3136
3200
|
|
|
3137
3201
|
const remainingAccounts = this.getRemainingAccounts({
|
|
3138
|
-
userAccounts:
|
|
3139
|
-
|
|
3202
|
+
userAccounts: depositToTradeArgs?.isMakingNewAccount
|
|
3203
|
+
? []
|
|
3204
|
+
: [this.getUserAccount(subAccountId)],
|
|
3205
|
+
useMarketLastSlotCache: false,
|
|
3140
3206
|
readablePerpMarketIndex: orderParams.marketIndex,
|
|
3207
|
+
readableSpotMarketIndexes: isDepositToTradeTx
|
|
3208
|
+
? [depositToTradeArgs?.depositMarketIndex]
|
|
3209
|
+
: undefined,
|
|
3141
3210
|
});
|
|
3142
3211
|
|
|
3143
3212
|
return await this.program.instruction.placePerpOrder(orderParams, {
|
package/src/math/margin.ts
CHANGED
|
@@ -7,10 +7,19 @@ import {
|
|
|
7
7
|
AMM_RESERVE_PRECISION,
|
|
8
8
|
MAX_PREDICTION_PRICE,
|
|
9
9
|
BASE_PRECISION,
|
|
10
|
+
MARGIN_PRECISION,
|
|
11
|
+
PRICE_PRECISION,
|
|
12
|
+
QUOTE_PRECISION,
|
|
10
13
|
} from '../constants/numericConstants';
|
|
11
14
|
import { BN } from '@coral-xyz/anchor';
|
|
12
15
|
import { OraclePriceData } from '../oracles/types';
|
|
13
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
calculateMarketMarginRatio,
|
|
18
|
+
calculateScaledInitialAssetWeight,
|
|
19
|
+
DriftClient,
|
|
20
|
+
PerpMarketAccount,
|
|
21
|
+
PerpPosition,
|
|
22
|
+
} from '..';
|
|
14
23
|
import { isVariant } from '../types';
|
|
15
24
|
import { assert } from '../assert/assert';
|
|
16
25
|
|
|
@@ -194,3 +203,130 @@ export function calculatePerpLiabilityValue(
|
|
|
194
203
|
return baseAssetAmount.abs().mul(oraclePrice).div(BASE_PRECISION);
|
|
195
204
|
}
|
|
196
205
|
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Calculates the margin required to open a trade, in quote amount. Only accounts for the trade size as a scalar value, does not account for the trade direction or current open positions and whether the trade would _actually_ be risk-increasing and use any extra collateral.
|
|
209
|
+
* @param targetMarketIndex
|
|
210
|
+
* @param baseSize
|
|
211
|
+
* @returns
|
|
212
|
+
*/
|
|
213
|
+
export function calculateMarginUSDCRequiredForTrade(
|
|
214
|
+
driftClient: DriftClient,
|
|
215
|
+
targetMarketIndex: number,
|
|
216
|
+
baseSize: BN,
|
|
217
|
+
userMaxMarginRatio?: number
|
|
218
|
+
): BN {
|
|
219
|
+
const targetMarket = driftClient.getPerpMarketAccount(targetMarketIndex);
|
|
220
|
+
const oracleData = driftClient.getOracleDataForPerpMarket(
|
|
221
|
+
targetMarket.marketIndex
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
const perpLiabilityValue = calculatePerpLiabilityValue(
|
|
225
|
+
baseSize,
|
|
226
|
+
oracleData.price,
|
|
227
|
+
isVariant(targetMarket.contractType, 'prediction')
|
|
228
|
+
);
|
|
229
|
+
|
|
230
|
+
const marginRequired = new BN(
|
|
231
|
+
calculateMarketMarginRatio(
|
|
232
|
+
targetMarket,
|
|
233
|
+
baseSize.abs(),
|
|
234
|
+
'Initial',
|
|
235
|
+
userMaxMarginRatio
|
|
236
|
+
)
|
|
237
|
+
)
|
|
238
|
+
.mul(perpLiabilityValue)
|
|
239
|
+
.div(MARGIN_PRECISION);
|
|
240
|
+
|
|
241
|
+
return marginRequired;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Similar to calculatetMarginUSDCRequiredForTrade, but calculates how much of a given collateral is required to cover the margin requirements for a given trade. Basically does the same thing as getMarginUSDCRequiredForTrade but also accounts for asset weight of the selected collateral.
|
|
246
|
+
*
|
|
247
|
+
* Returns collateral required in the precision of the target collateral market.
|
|
248
|
+
*/
|
|
249
|
+
export function calculateCollateralDepositRequiredForTrade(
|
|
250
|
+
driftClient: DriftClient,
|
|
251
|
+
targetMarketIndex: number,
|
|
252
|
+
baseSize: BN,
|
|
253
|
+
collateralIndex: number,
|
|
254
|
+
userMaxMarginRatio?: number
|
|
255
|
+
): BN {
|
|
256
|
+
const marginRequiredUsdc = calculateMarginUSDCRequiredForTrade(
|
|
257
|
+
driftClient,
|
|
258
|
+
targetMarketIndex,
|
|
259
|
+
baseSize,
|
|
260
|
+
userMaxMarginRatio
|
|
261
|
+
);
|
|
262
|
+
|
|
263
|
+
const collateralMarket = driftClient.getSpotMarketAccount(collateralIndex);
|
|
264
|
+
|
|
265
|
+
const collateralOracleData =
|
|
266
|
+
driftClient.getOracleDataForSpotMarket(collateralIndex);
|
|
267
|
+
|
|
268
|
+
const scaledAssetWeight = calculateScaledInitialAssetWeight(
|
|
269
|
+
collateralMarket,
|
|
270
|
+
collateralOracleData.price
|
|
271
|
+
);
|
|
272
|
+
|
|
273
|
+
// Base amount required to deposit = (marginRequiredUsdc / priceOfAsset) / assetWeight .. (E.g. $100 required / $10000 price / 0.5 weight)
|
|
274
|
+
const baseAmountRequired = driftClient
|
|
275
|
+
.convertToSpotPrecision(collateralIndex, marginRequiredUsdc)
|
|
276
|
+
.mul(PRICE_PRECISION) // adjust for division by oracle price
|
|
277
|
+
.mul(SPOT_MARKET_WEIGHT_PRECISION) // adjust for division by scaled asset weight
|
|
278
|
+
.div(collateralOracleData.price)
|
|
279
|
+
.div(scaledAssetWeight)
|
|
280
|
+
.div(QUOTE_PRECISION); // adjust for marginRequiredUsdc value's QUOTE_PRECISION
|
|
281
|
+
|
|
282
|
+
// TODO : Round by step size?
|
|
283
|
+
|
|
284
|
+
return baseAmountRequired;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
export function calculateCollateralValueOfDeposit(
|
|
288
|
+
driftClient: DriftClient,
|
|
289
|
+
collateralIndex: number,
|
|
290
|
+
baseSize: BN
|
|
291
|
+
): BN {
|
|
292
|
+
const collateralMarket = driftClient.getSpotMarketAccount(collateralIndex);
|
|
293
|
+
|
|
294
|
+
const collateralOracleData =
|
|
295
|
+
driftClient.getOracleDataForSpotMarket(collateralIndex);
|
|
296
|
+
|
|
297
|
+
const scaledAssetWeight = calculateScaledInitialAssetWeight(
|
|
298
|
+
collateralMarket,
|
|
299
|
+
collateralOracleData.price
|
|
300
|
+
);
|
|
301
|
+
|
|
302
|
+
// CollateralBaseValue = oracle price * collateral base amount (and shift to QUOTE_PRECISION)
|
|
303
|
+
const collateralBaseValue = collateralOracleData.price
|
|
304
|
+
.mul(baseSize)
|
|
305
|
+
.mul(QUOTE_PRECISION)
|
|
306
|
+
.div(PRICE_PRECISION)
|
|
307
|
+
.div(new BN(10).pow(new BN(collateralMarket.decimals)));
|
|
308
|
+
|
|
309
|
+
const depositCollateralValue = collateralBaseValue
|
|
310
|
+
.mul(scaledAssetWeight)
|
|
311
|
+
.div(SPOT_MARKET_WEIGHT_PRECISION);
|
|
312
|
+
|
|
313
|
+
return depositCollateralValue;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
export function calculateLiquidationPrice(
|
|
317
|
+
freeCollateral: BN,
|
|
318
|
+
freeCollateralDelta: BN,
|
|
319
|
+
oraclePrice: BN
|
|
320
|
+
): BN {
|
|
321
|
+
const liqPriceDelta = freeCollateral
|
|
322
|
+
.mul(QUOTE_PRECISION)
|
|
323
|
+
.div(freeCollateralDelta);
|
|
324
|
+
|
|
325
|
+
const liqPrice = oraclePrice.sub(liqPriceDelta);
|
|
326
|
+
|
|
327
|
+
if (liqPrice.lt(ZERO)) {
|
|
328
|
+
return new BN(-1);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
return liqPrice;
|
|
332
|
+
}
|
package/src/user.ts
CHANGED
|
@@ -78,6 +78,8 @@ import {
|
|
|
78
78
|
import { calculateMarketOpenBidAsk } from './math/amm';
|
|
79
79
|
import {
|
|
80
80
|
calculateBaseAssetValueWithOracle,
|
|
81
|
+
calculateCollateralDepositRequiredForTrade,
|
|
82
|
+
calculateMarginUSDCRequiredForTrade,
|
|
81
83
|
calculateWorstCaseBaseAssetAmount,
|
|
82
84
|
} from './math/margin';
|
|
83
85
|
import { OraclePriceData } from './oracles/types';
|
|
@@ -2274,6 +2276,7 @@ export class User {
|
|
|
2274
2276
|
* @param estimatedEntryPrice
|
|
2275
2277
|
* @param marginCategory // allow Initial to be passed in if we are trying to calculate price for DLP de-risking
|
|
2276
2278
|
* @param includeOpenOrders
|
|
2279
|
+
* @param offsetCollateral // allows calculating the liquidation price after this offset collateral is added to the user's account (e.g. : what will the liquidation price be for this position AFTER I deposit $x worth of collateral)
|
|
2277
2280
|
* @returns Precision : PRICE_PRECISION
|
|
2278
2281
|
*/
|
|
2279
2282
|
public liquidationPrice(
|
|
@@ -2281,7 +2284,8 @@ export class User {
|
|
|
2281
2284
|
positionBaseSizeChange: BN = ZERO,
|
|
2282
2285
|
estimatedEntryPrice: BN = ZERO,
|
|
2283
2286
|
marginCategory: MarginCategory = 'Maintenance',
|
|
2284
|
-
includeOpenOrders = false
|
|
2287
|
+
includeOpenOrders = false,
|
|
2288
|
+
offsetCollateral = ZERO
|
|
2285
2289
|
): BN {
|
|
2286
2290
|
const totalCollateral = this.getTotalCollateral(marginCategory);
|
|
2287
2291
|
const marginRequirement = this.getMarginRequirement(
|
|
@@ -2290,7 +2294,10 @@ export class User {
|
|
|
2290
2294
|
false,
|
|
2291
2295
|
includeOpenOrders
|
|
2292
2296
|
);
|
|
2293
|
-
let freeCollateral = BN.max(
|
|
2297
|
+
let freeCollateral = BN.max(
|
|
2298
|
+
ZERO,
|
|
2299
|
+
totalCollateral.sub(marginRequirement)
|
|
2300
|
+
).add(offsetCollateral);
|
|
2294
2301
|
|
|
2295
2302
|
const oracle =
|
|
2296
2303
|
this.driftClient.getPerpMarketAccount(marketIndex).amm.oracle;
|
|
@@ -2593,6 +2600,32 @@ export class User {
|
|
|
2593
2600
|
);
|
|
2594
2601
|
}
|
|
2595
2602
|
|
|
2603
|
+
public getMarginUSDCRequiredForTrade(
|
|
2604
|
+
targetMarketIndex: number,
|
|
2605
|
+
baseSize: BN
|
|
2606
|
+
): BN {
|
|
2607
|
+
return calculateMarginUSDCRequiredForTrade(
|
|
2608
|
+
this.driftClient,
|
|
2609
|
+
targetMarketIndex,
|
|
2610
|
+
baseSize,
|
|
2611
|
+
this.getUserAccount().maxMarginRatio
|
|
2612
|
+
);
|
|
2613
|
+
}
|
|
2614
|
+
|
|
2615
|
+
public getCollateralDepositRequiredForTrade(
|
|
2616
|
+
targetMarketIndex: number,
|
|
2617
|
+
baseSize: BN,
|
|
2618
|
+
collateralIndex: number
|
|
2619
|
+
): BN {
|
|
2620
|
+
return calculateCollateralDepositRequiredForTrade(
|
|
2621
|
+
this.driftClient,
|
|
2622
|
+
targetMarketIndex,
|
|
2623
|
+
baseSize,
|
|
2624
|
+
collateralIndex,
|
|
2625
|
+
this.getUserAccount().maxMarginRatio
|
|
2626
|
+
);
|
|
2627
|
+
}
|
|
2628
|
+
|
|
2596
2629
|
/**
|
|
2597
2630
|
* Get the maximum trade size for a given market, taking into account the user's current leverage, positions, collateral, etc.
|
|
2598
2631
|
*
|
package/tests/ci/idl.ts
CHANGED
|
@@ -51,7 +51,9 @@ describe('Verify IDL', function () {
|
|
|
51
51
|
);
|
|
52
52
|
|
|
53
53
|
if (onChainIdl === null) {
|
|
54
|
-
throw new Error(
|
|
54
|
+
throw new Error(
|
|
55
|
+
`onChainIdl for ${mainnetDriftClient.program.programId.toBase58()} null`
|
|
56
|
+
);
|
|
55
57
|
}
|
|
56
58
|
|
|
57
59
|
// anchor idl init seems to strip the metadata
|
|
@@ -65,13 +67,20 @@ describe('Verify IDL', function () {
|
|
|
65
67
|
const encodedSdkIdl = JSON.stringify(sdkIdl);
|
|
66
68
|
|
|
67
69
|
try {
|
|
68
|
-
assert(
|
|
70
|
+
assert(
|
|
71
|
+
encodedSdkIdl === encodedMainnetIdl,
|
|
72
|
+
'on-chain IDL does not match SDK IDL'
|
|
73
|
+
);
|
|
69
74
|
} catch (error) {
|
|
70
75
|
const diff = {};
|
|
71
76
|
for (const key of IDL_KEYS_TO_CHECK) {
|
|
72
77
|
const onChainItems = onChainIdl[key];
|
|
73
78
|
const sdkItems = sdkIdl[key];
|
|
74
|
-
for (
|
|
79
|
+
for (
|
|
80
|
+
let i = 0;
|
|
81
|
+
i < Math.max(onChainItems.length, sdkItems.length);
|
|
82
|
+
i++
|
|
83
|
+
) {
|
|
75
84
|
let onChainItem = null;
|
|
76
85
|
let sdkItem = null;
|
|
77
86
|
if (i < onChainItems.length) {
|