@drift-labs/sdk 0.2.0-master.11 → 0.2.0-master.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/clearingHouse.d.ts +7 -2
- package/lib/clearingHouse.js +157 -37
- package/lib/clearingHouseUser.d.ts +10 -15
- package/lib/clearingHouseUser.js +92 -74
- package/lib/config.js +1 -1
- package/lib/constants/banks.d.ts +2 -2
- package/lib/constants/banks.js +4 -3
- package/lib/constants/numericConstants.d.ts +2 -0
- package/lib/constants/numericConstants.js +3 -1
- package/lib/events/eventList.js +3 -0
- package/lib/events/types.d.ts +2 -1
- package/lib/factory/bigNum.d.ts +1 -0
- package/lib/factory/bigNum.js +37 -11
- package/lib/idl/clearing_house.json +97 -19
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/math/bankBalance.d.ts +3 -1
- package/lib/math/bankBalance.js +54 -1
- package/lib/math/margin.d.ts +11 -0
- package/lib/math/margin.js +72 -0
- package/lib/math/market.d.ts +4 -1
- package/lib/math/market.js +35 -1
- package/lib/math/position.d.ts +8 -0
- package/lib/math/position.js +42 -12
- package/lib/orders.d.ts +1 -2
- package/lib/orders.js +2 -77
- package/lib/tokenFaucet.d.ts +1 -0
- package/lib/tokenFaucet.js +23 -12
- package/lib/tx/retryTxSender.js +9 -2
- package/lib/types.d.ts +24 -3
- package/lib/types.js +6 -0
- package/lib/util/getTokenAddress.d.ts +2 -0
- package/lib/util/getTokenAddress.js +9 -0
- package/package.json +1 -1
- package/src/clearingHouse.ts +301 -47
- package/src/clearingHouseConfig.js +2 -0
- package/src/clearingHouseUser.ts +213 -104
- package/src/clearingHouseUserConfig.js +2 -0
- package/src/config.ts +1 -1
- package/src/constants/banks.js +42 -0
- package/src/constants/banks.ts +6 -3
- package/src/constants/markets.js +42 -0
- package/src/constants/numericConstants.js +41 -0
- package/src/constants/numericConstants.ts +3 -0
- package/src/events/eventList.ts +3 -0
- package/src/events/types.ts +2 -0
- package/src/factory/bigNum.js +37 -11
- package/src/factory/bigNum.ts +43 -13
- package/src/idl/clearing_house.json +97 -19
- package/src/index.js +67 -98
- package/src/index.ts +1 -0
- package/src/math/bankBalance.ts +98 -1
- package/src/math/margin.ts +124 -0
- package/src/math/market.ts +66 -1
- package/src/math/position.ts +59 -9
- package/src/orders.ts +4 -157
- package/src/tokenFaucet.js +189 -0
- package/src/tokenFaucet.ts +38 -15
- package/src/tx/retryTxSender.ts +11 -3
- package/src/types.js +12 -1
- package/src/types.ts +25 -3
- package/src/{accounts/fetch.js → util/computeUnits.js} +11 -13
- package/src/util/getTokenAddress.js +9 -0
- package/src/util/getTokenAddress.ts +18 -0
- package/tests/bn/test.ts +2 -0
- package/src/addresses/pda.js +0 -104
- package/src/math/bankBalance.js +0 -75
- package/src/math/market.js +0 -57
- package/src/math/orders.js +0 -110
- package/src/math/position.js +0 -140
- package/src/orders.js +0 -134
- package/src/tx/retryTxSender.js +0 -188
package/lib/orders.js
CHANGED
|
@@ -1,85 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.calculateAmountToTradeForTriggerLimit = exports.calculateAmountToTradeForLimit = exports.calculateBaseAssetAmountMarketCanExecute =
|
|
3
|
+
exports.calculateAmountToTradeForTriggerLimit = exports.calculateAmountToTradeForLimit = exports.calculateBaseAssetAmountMarketCanExecute = void 0;
|
|
4
4
|
const types_1 = require("./types");
|
|
5
5
|
const _1 = require(".");
|
|
6
|
-
const market_1 = require("./math/market");
|
|
7
6
|
const numericConstants_1 = require("./constants/numericConstants");
|
|
8
7
|
const amm_1 = require("./math/amm");
|
|
9
|
-
const position_1 = require("./math/position");
|
|
10
|
-
function calculateNewStateAfterOrder(userAccount, userPosition, market, order) {
|
|
11
|
-
if ((0, types_1.isVariant)(order.status, 'init')) {
|
|
12
|
-
return null;
|
|
13
|
-
}
|
|
14
|
-
const baseAssetAmountToTrade = calculateBaseAssetAmountMarketCanExecute(market, order);
|
|
15
|
-
if (baseAssetAmountToTrade.lt(market.amm.baseAssetAmountStepSize)) {
|
|
16
|
-
return null;
|
|
17
|
-
}
|
|
18
|
-
const userAccountAfter = Object.assign({}, userAccount);
|
|
19
|
-
const userPositionAfter = Object.assign({}, userPosition);
|
|
20
|
-
const currentPositionDirection = (0, position_1.positionCurrentDirection)(userPosition);
|
|
21
|
-
const increasePosition = userPosition.baseAssetAmount.eq(numericConstants_1.ZERO) ||
|
|
22
|
-
isSameDirection(order.direction, currentPositionDirection);
|
|
23
|
-
if (increasePosition) {
|
|
24
|
-
const marketAfter = (0, market_1.calculateNewMarketAfterTrade)(baseAssetAmountToTrade, order.direction, market);
|
|
25
|
-
const { quoteAssetAmountSwapped, baseAssetAmountSwapped } = calculateAmountSwapped(market, marketAfter);
|
|
26
|
-
userPositionAfter.baseAssetAmount = userPositionAfter.baseAssetAmount.add(baseAssetAmountSwapped);
|
|
27
|
-
userPositionAfter.quoteAssetAmount = userPositionAfter.quoteAssetAmount.add(quoteAssetAmountSwapped);
|
|
28
|
-
return [userAccountAfter, userPositionAfter, marketAfter];
|
|
29
|
-
}
|
|
30
|
-
else {
|
|
31
|
-
const reversePosition = baseAssetAmountToTrade.gt(userPosition.baseAssetAmount.abs());
|
|
32
|
-
if (reversePosition) {
|
|
33
|
-
const intermediateMarket = (0, market_1.calculateNewMarketAfterTrade)(userPosition.baseAssetAmount, (0, position_1.findDirectionToClose)(userPosition), market);
|
|
34
|
-
const { quoteAssetAmountSwapped: baseAssetValue } = calculateAmountSwapped(market, intermediateMarket);
|
|
35
|
-
let pnl;
|
|
36
|
-
if ((0, types_1.isVariant)(currentPositionDirection, 'long')) {
|
|
37
|
-
pnl = baseAssetValue.sub(userPosition.quoteAssetAmount);
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
pnl = userPosition.quoteAssetAmount.sub(baseAssetValue);
|
|
41
|
-
}
|
|
42
|
-
userAccountAfter.collateral = userAccountAfter.collateral.add(pnl);
|
|
43
|
-
const baseAssetAmountLeft = baseAssetAmountToTrade.sub(userPosition.baseAssetAmount.abs());
|
|
44
|
-
const marketAfter = (0, market_1.calculateNewMarketAfterTrade)(baseAssetAmountLeft, order.direction, intermediateMarket);
|
|
45
|
-
const { quoteAssetAmountSwapped, baseAssetAmountSwapped } = calculateAmountSwapped(intermediateMarket, marketAfter);
|
|
46
|
-
userPositionAfter.quoteAssetAmount = quoteAssetAmountSwapped;
|
|
47
|
-
userPositionAfter.baseAssetAmount = baseAssetAmountSwapped;
|
|
48
|
-
return [userAccountAfter, userPositionAfter, marketAfter];
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
const marketAfter = (0, market_1.calculateNewMarketAfterTrade)(baseAssetAmountToTrade, order.direction, market);
|
|
52
|
-
const { quoteAssetAmountSwapped: baseAssetValue, baseAssetAmountSwapped, } = calculateAmountSwapped(market, marketAfter);
|
|
53
|
-
const costBasisRealized = userPosition.quoteAssetAmount
|
|
54
|
-
.mul(baseAssetAmountSwapped.abs())
|
|
55
|
-
.div(userPosition.baseAssetAmount.abs());
|
|
56
|
-
let pnl;
|
|
57
|
-
if ((0, types_1.isVariant)(currentPositionDirection, 'long')) {
|
|
58
|
-
pnl = baseAssetValue.sub(costBasisRealized);
|
|
59
|
-
}
|
|
60
|
-
else {
|
|
61
|
-
pnl = costBasisRealized.sub(baseAssetValue);
|
|
62
|
-
}
|
|
63
|
-
userAccountAfter.collateral = userAccountAfter.collateral.add(pnl);
|
|
64
|
-
userPositionAfter.baseAssetAmount = userPositionAfter.baseAssetAmount.add(baseAssetAmountSwapped);
|
|
65
|
-
userPositionAfter.quoteAssetAmount =
|
|
66
|
-
userPositionAfter.quoteAssetAmount.sub(costBasisRealized);
|
|
67
|
-
return [userAccountAfter, userPositionAfter, marketAfter];
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
exports.calculateNewStateAfterOrder = calculateNewStateAfterOrder;
|
|
72
|
-
function calculateAmountSwapped(marketBefore, marketAfter) {
|
|
73
|
-
return {
|
|
74
|
-
quoteAssetAmountSwapped: marketBefore.amm.quoteAssetReserve
|
|
75
|
-
.sub(marketAfter.amm.quoteAssetReserve)
|
|
76
|
-
.abs()
|
|
77
|
-
.mul(marketBefore.amm.pegMultiplier)
|
|
78
|
-
.div(numericConstants_1.PEG_PRECISION)
|
|
79
|
-
.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO),
|
|
80
|
-
baseAssetAmountSwapped: marketBefore.amm.baseAssetReserve.sub(marketAfter.amm.baseAssetReserve),
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
8
|
function calculateBaseAssetAmountMarketCanExecute(market, order, oraclePriceData) {
|
|
84
9
|
if ((0, types_1.isVariant)(order.orderType, 'limit')) {
|
|
85
10
|
return calculateAmountToTradeForLimit(market, order, oraclePriceData);
|
|
@@ -103,7 +28,7 @@ function calculateAmountToTradeForLimit(market, order, oraclePriceData) {
|
|
|
103
28
|
}
|
|
104
29
|
limitPrice = oraclePriceData.price.add(order.oraclePriceOffset);
|
|
105
30
|
}
|
|
106
|
-
const [maxAmountToTrade, direction] = (0, amm_1.calculateMaxBaseAssetAmountToTrade)(market.amm, limitPrice, order.direction);
|
|
31
|
+
const [maxAmountToTrade, direction] = (0, amm_1.calculateMaxBaseAssetAmountToTrade)(market.amm, limitPrice, order.direction, oraclePriceData);
|
|
107
32
|
const baseAssetAmount = (0, _1.standardizeBaseAssetAmount)(maxAmountToTrade, market.amm.baseAssetAmountStepSize);
|
|
108
33
|
// Check that directions are the same
|
|
109
34
|
const sameDirection = isSameDirection(direction, order.direction);
|
package/lib/tokenFaucet.d.ts
CHANGED
|
@@ -21,6 +21,7 @@ export declare class TokenFaucet {
|
|
|
21
21
|
getFaucetConfigPublicKey(): Promise<PublicKey>;
|
|
22
22
|
initialize(): Promise<TransactionSignature>;
|
|
23
23
|
fetchState(): Promise<any>;
|
|
24
|
+
private mintToUserIx;
|
|
24
25
|
mintToUser(userTokenAccount: PublicKey, amount: BN): Promise<TransactionSignature>;
|
|
25
26
|
transferMintAuthority(): Promise<TransactionSignature>;
|
|
26
27
|
createAssociatedTokenAccountAndMintTo(userPublicKey: PublicKey, amount: BN): Promise<[PublicKey, TransactionSignature]>;
|
package/lib/tokenFaucet.js
CHANGED
|
@@ -73,8 +73,8 @@ class TokenFaucet {
|
|
|
73
73
|
async fetchState() {
|
|
74
74
|
return await this.program.account.faucetConfig.fetch(await this.getFaucetConfigPublicKey());
|
|
75
75
|
}
|
|
76
|
-
async
|
|
77
|
-
return
|
|
76
|
+
async mintToUserIx(userTokenAccount, amount) {
|
|
77
|
+
return this.program.instruction.mintToUser(amount, {
|
|
78
78
|
accounts: {
|
|
79
79
|
faucetConfig: await this.getFaucetConfigPublicKey(),
|
|
80
80
|
mintAccount: this.mint,
|
|
@@ -84,6 +84,12 @@ class TokenFaucet {
|
|
|
84
84
|
},
|
|
85
85
|
});
|
|
86
86
|
}
|
|
87
|
+
async mintToUser(userTokenAccount, amount) {
|
|
88
|
+
const mintIx = await this.mintToUserIx(userTokenAccount, amount);
|
|
89
|
+
const tx = new web3_js_1.Transaction().add(mintIx);
|
|
90
|
+
const txSig = await this.program.provider.sendAndConfirm(tx, [], this.opts);
|
|
91
|
+
return txSig;
|
|
92
|
+
}
|
|
87
93
|
async transferMintAuthority() {
|
|
88
94
|
return await this.program.rpc.transferMintAuthority({
|
|
89
95
|
accounts: {
|
|
@@ -96,8 +102,21 @@ class TokenFaucet {
|
|
|
96
102
|
});
|
|
97
103
|
}
|
|
98
104
|
async createAssociatedTokenAccountAndMintTo(userPublicKey, amount) {
|
|
105
|
+
const tx = new web3_js_1.Transaction();
|
|
99
106
|
const [associatedTokenPublicKey, createAssociatedAccountIx, mintToTx] = await this.createAssociatedTokenAccountAndMintToInstructions(userPublicKey, amount);
|
|
100
|
-
|
|
107
|
+
let associatedTokenAccountExists = false;
|
|
108
|
+
try {
|
|
109
|
+
const assosciatedTokenAccount = await this.connection.getAccountInfo(associatedTokenPublicKey);
|
|
110
|
+
associatedTokenAccountExists = !!assosciatedTokenAccount;
|
|
111
|
+
}
|
|
112
|
+
catch (e) {
|
|
113
|
+
// token account doesn't exist
|
|
114
|
+
associatedTokenAccountExists = false;
|
|
115
|
+
}
|
|
116
|
+
const skipAccountCreation = associatedTokenAccountExists;
|
|
117
|
+
if (!skipAccountCreation)
|
|
118
|
+
tx.add(createAssociatedAccountIx);
|
|
119
|
+
tx.add(mintToTx);
|
|
101
120
|
const txSig = await this.program.provider.sendAndConfirm(tx, [], this.opts);
|
|
102
121
|
return [associatedTokenPublicKey, txSig];
|
|
103
122
|
}
|
|
@@ -105,15 +124,7 @@ class TokenFaucet {
|
|
|
105
124
|
const state = await this.fetchState();
|
|
106
125
|
const associateTokenPublicKey = await this.getAssosciatedMockUSDMintAddress({ userPubKey: userPublicKey });
|
|
107
126
|
const createAssociatedAccountIx = spl_token_1.Token.createAssociatedTokenAccountInstruction(spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID, spl_token_1.TOKEN_PROGRAM_ID, state.mint, associateTokenPublicKey, userPublicKey, this.wallet.publicKey);
|
|
108
|
-
const mintToIx = await this.
|
|
109
|
-
accounts: {
|
|
110
|
-
faucetConfig: await this.getFaucetConfigPublicKey(),
|
|
111
|
-
mintAccount: state.mint,
|
|
112
|
-
userTokenAccount: associateTokenPublicKey,
|
|
113
|
-
mintAuthority: state.mintAuthority,
|
|
114
|
-
tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
|
|
115
|
-
},
|
|
116
|
-
});
|
|
127
|
+
const mintToIx = await this.mintToUserIx(associateTokenPublicKey, amount);
|
|
117
128
|
return [associateTokenPublicKey, createAssociatedAccountIx, mintToIx];
|
|
118
129
|
}
|
|
119
130
|
async getAssosciatedMockUSDMintAddress(props) {
|
package/lib/tx/retryTxSender.js
CHANGED
|
@@ -25,8 +25,15 @@ class RetryTxSender {
|
|
|
25
25
|
await this.prepareTx(tx, additionalSigners, opts);
|
|
26
26
|
const rawTransaction = tx.serialize();
|
|
27
27
|
const startTime = this.getTimestamp();
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
let txid;
|
|
29
|
+
try {
|
|
30
|
+
txid = await this.provider.connection.sendRawTransaction(rawTransaction, opts);
|
|
31
|
+
this.sendToAdditionalConnections(rawTransaction, opts);
|
|
32
|
+
}
|
|
33
|
+
catch (e) {
|
|
34
|
+
console.error(e);
|
|
35
|
+
throw e;
|
|
36
|
+
}
|
|
30
37
|
let done = false;
|
|
31
38
|
const resolveReference = {
|
|
32
39
|
resolve: undefined,
|
package/lib/types.d.ts
CHANGED
|
@@ -113,6 +113,12 @@ export declare class OrderActionExplanation {
|
|
|
113
113
|
static readonly MARKET_ORDER_FILLED_TO_LIMIT_PRICE: {
|
|
114
114
|
marketOrderFilledToLimitPrice: {};
|
|
115
115
|
};
|
|
116
|
+
static readonly CANCELED_FOR_LIQUIDATION: {
|
|
117
|
+
canceledForLiquidation: {};
|
|
118
|
+
};
|
|
119
|
+
static readonly MARKET_ORDER_AUCTION_EXPIRED: {
|
|
120
|
+
marketOrderAuctionExpired: {};
|
|
121
|
+
};
|
|
116
122
|
}
|
|
117
123
|
export declare class OrderTriggerCondition {
|
|
118
124
|
static readonly ABOVE: {
|
|
@@ -192,6 +198,7 @@ export declare type LiquidationRecord = {
|
|
|
192
198
|
liquidationType: LiquidationType;
|
|
193
199
|
marginRequirement: BN;
|
|
194
200
|
totalCollateral: BN;
|
|
201
|
+
liquidationId: number;
|
|
195
202
|
liquidatePerp: LiquidatePerpRecord;
|
|
196
203
|
liquidateBorrow: LiquidateBorrowRecord;
|
|
197
204
|
liquidateBorrowForPerpPnl: LiquidateBorrowForPerpPnlRecord;
|
|
@@ -248,14 +255,23 @@ export declare type LiquidatePerpPnlForDepositRecord = {
|
|
|
248
255
|
assetPrice: BN;
|
|
249
256
|
assetTransfer: BN;
|
|
250
257
|
};
|
|
258
|
+
export declare type SettlePnlRecord = {
|
|
259
|
+
ts: BN;
|
|
260
|
+
marketIndex: BN;
|
|
261
|
+
pnl: BN;
|
|
262
|
+
baseAssetAmount: BN;
|
|
263
|
+
quoteAssetAmountAfter: BN;
|
|
264
|
+
quoteEntryamount: BN;
|
|
265
|
+
oraclePrice: BN;
|
|
266
|
+
};
|
|
251
267
|
export declare type OrderRecord = {
|
|
252
268
|
ts: BN;
|
|
253
269
|
taker: PublicKey;
|
|
254
270
|
maker: PublicKey;
|
|
255
271
|
takerOrder: Order;
|
|
256
272
|
makerOrder: Order;
|
|
257
|
-
|
|
258
|
-
|
|
273
|
+
takerPnl: BN;
|
|
274
|
+
makerPnl: BN;
|
|
259
275
|
action: OrderAction;
|
|
260
276
|
actionExplanation: OrderActionExplanation;
|
|
261
277
|
filler: PublicKey;
|
|
@@ -313,6 +329,10 @@ export declare type MarketAccount = {
|
|
|
313
329
|
nextFillRecordId: BN;
|
|
314
330
|
pnlPool: PoolBalance;
|
|
315
331
|
liquidationFee: BN;
|
|
332
|
+
imfFactor: BN;
|
|
333
|
+
unsettledImfFactor: BN;
|
|
334
|
+
unsettledInitialAssetWeight: number;
|
|
335
|
+
unsettledMaintenanceAssetWeight: number;
|
|
316
336
|
};
|
|
317
337
|
export declare type BankAccount = {
|
|
318
338
|
bankIndex: BN;
|
|
@@ -336,6 +356,7 @@ export declare type BankAccount = {
|
|
|
336
356
|
initialLiabilityWeight: BN;
|
|
337
357
|
maintenanceLiabilityWeight: BN;
|
|
338
358
|
liquidationFee: BN;
|
|
359
|
+
imfFactor: BN;
|
|
339
360
|
};
|
|
340
361
|
export declare type PoolBalance = {
|
|
341
362
|
balance: BN;
|
|
@@ -393,7 +414,6 @@ export declare type UserPosition = {
|
|
|
393
414
|
quoteAssetAmount: BN;
|
|
394
415
|
quoteEntryAmount: BN;
|
|
395
416
|
openOrders: BN;
|
|
396
|
-
unsettledPnl: BN;
|
|
397
417
|
openBids: BN;
|
|
398
418
|
openAsks: BN;
|
|
399
419
|
};
|
|
@@ -414,6 +434,7 @@ export declare type UserAccount = {
|
|
|
414
434
|
positions: UserPosition[];
|
|
415
435
|
orders: Order[];
|
|
416
436
|
beingLiquidated: boolean;
|
|
437
|
+
nextLiquidationId: number;
|
|
417
438
|
};
|
|
418
439
|
export declare type UserBankBalance = {
|
|
419
440
|
bankIndex: BN;
|
package/lib/types.js
CHANGED
|
@@ -70,6 +70,12 @@ OrderActionExplanation.ORACLE_PRICE_BREACHED_LIMIT_PRICE = {
|
|
|
70
70
|
OrderActionExplanation.MARKET_ORDER_FILLED_TO_LIMIT_PRICE = {
|
|
71
71
|
marketOrderFilledToLimitPrice: {},
|
|
72
72
|
};
|
|
73
|
+
OrderActionExplanation.CANCELED_FOR_LIQUIDATION = {
|
|
74
|
+
canceledForLiquidation: {},
|
|
75
|
+
};
|
|
76
|
+
OrderActionExplanation.MARKET_ORDER_AUCTION_EXPIRED = {
|
|
77
|
+
marketOrderAuctionExpired: {},
|
|
78
|
+
};
|
|
73
79
|
class OrderTriggerCondition {
|
|
74
80
|
}
|
|
75
81
|
exports.OrderTriggerCondition = OrderTriggerCondition;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getTokenAddress = void 0;
|
|
4
|
+
const spl_token_1 = require("@solana/spl-token");
|
|
5
|
+
const web3_js_1 = require("@solana/web3.js");
|
|
6
|
+
const getTokenAddress = (mintAddress, userPubKey) => {
|
|
7
|
+
return spl_token_1.Token.getAssociatedTokenAddress(spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID, spl_token_1.TOKEN_PROGRAM_ID, new web3_js_1.PublicKey(mintAddress), new web3_js_1.PublicKey(userPubKey));
|
|
8
|
+
};
|
|
9
|
+
exports.getTokenAddress = getTokenAddress;
|