@drift-labs/sdk 0.2.0-master.18 → 0.2.0-master.20
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 +11 -11
- package/lib/clearingHouse.js +78 -18
- package/lib/clearingHouseUser.js +7 -25
- package/lib/clearingHouseUserStats.d.ts +2 -1
- package/lib/clearingHouseUserStats.js +13 -0
- package/lib/config.js +1 -1
- package/lib/events/types.d.ts +2 -1
- package/lib/events/types.js +1 -0
- package/lib/idl/clearing_house.json +200 -129
- package/lib/index.d.ts +0 -1
- package/lib/index.js +0 -1
- package/lib/math/amm.d.ts +1 -0
- package/lib/math/amm.js +13 -1
- package/lib/math/market.d.ts +1 -1
- package/lib/math/market.js +5 -5
- package/lib/math/orders.d.ts +3 -0
- package/lib/math/orders.js +35 -1
- package/lib/types.d.ts +25 -7
- package/package.json +1 -1
- package/src/clearingHouse.ts +113 -19
- package/src/clearingHouseUser.ts +11 -49
- package/src/clearingHouseUserStats.ts +23 -1
- package/src/config.ts +1 -1
- package/src/events/types.ts +3 -0
- package/src/idl/clearing_house.json +200 -129
- package/src/index.ts +0 -1
- package/src/math/amm.ts +27 -1
- package/src/math/market.ts +6 -6
- package/src/math/orders.ts +96 -1
- package/src/types.ts +27 -7
- package/lib/orders.d.ts +0 -7
- package/lib/orders.js +0 -59
- package/src/events/types.js +0 -20
- package/src/math/amm.js +0 -369
- package/src/orders.ts +0 -91
- package/src/types.js +0 -125
package/lib/index.d.ts
CHANGED
|
@@ -40,7 +40,6 @@ export * from './math/trade';
|
|
|
40
40
|
export * from './math/orders';
|
|
41
41
|
export * from './math/repeg';
|
|
42
42
|
export * from './math/margin';
|
|
43
|
-
export * from './orders';
|
|
44
43
|
export * from './orderParams';
|
|
45
44
|
export * from './slot/SlotSubscriber';
|
|
46
45
|
export * from './wallet';
|
package/lib/index.js
CHANGED
|
@@ -63,7 +63,6 @@ __exportStar(require("./math/trade"), exports);
|
|
|
63
63
|
__exportStar(require("./math/orders"), exports);
|
|
64
64
|
__exportStar(require("./math/repeg"), exports);
|
|
65
65
|
__exportStar(require("./math/margin"), exports);
|
|
66
|
-
__exportStar(require("./orders"), exports);
|
|
67
66
|
__exportStar(require("./orderParams"), exports);
|
|
68
67
|
__exportStar(require("./slot/SlotSubscriber"), exports);
|
|
69
68
|
__exportStar(require("./wallet"), exports);
|
package/lib/math/amm.d.ts
CHANGED
|
@@ -67,3 +67,4 @@ export declare function getSwapDirection(inputAssetType: AssetType, positionDire
|
|
|
67
67
|
export declare function calculateTerminalPrice(market: MarketAccount): BN;
|
|
68
68
|
export declare function calculateMaxBaseAssetAmountToTrade(amm: AMM, limit_price: BN, direction: PositionDirection, oraclePriceData?: OraclePriceData): [BN, PositionDirection];
|
|
69
69
|
export declare function calculateQuoteAssetAmountSwapped(quoteAssetReserves: BN, pegMultiplier: BN, swapDirection: SwapDirection): BN;
|
|
70
|
+
export declare function calculateMaxBaseAssetAmountFillable(amm: AMM, orderDirection: PositionDirection): BN;
|
package/lib/math/amm.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.calculateQuoteAssetAmountSwapped = exports.calculateMaxBaseAssetAmountToTrade = exports.calculateTerminalPrice = exports.getSwapDirection = exports.calculateSwapOutput = exports.calculateSpreadReserves = exports.calculateSpread = exports.calculateSpreadBN = exports.calculateMaxSpread = exports.calculateEffectiveLeverage = exports.calculateAmmReservesAfterSwap = exports.calculatePrice = exports.calculateBidAskPrice = exports.calculateUpdatedAMMSpreadReserves = exports.calculateUpdatedAMM = exports.calculateNewAmm = exports.calculateOptimalPegAndBudget = exports.calculatePegFromTargetPrice = void 0;
|
|
3
|
+
exports.calculateMaxBaseAssetAmountFillable = exports.calculateQuoteAssetAmountSwapped = exports.calculateMaxBaseAssetAmountToTrade = exports.calculateTerminalPrice = exports.getSwapDirection = exports.calculateSwapOutput = exports.calculateSpreadReserves = exports.calculateSpread = exports.calculateSpreadBN = exports.calculateMaxSpread = exports.calculateEffectiveLeverage = exports.calculateAmmReservesAfterSwap = exports.calculatePrice = exports.calculateBidAskPrice = exports.calculateUpdatedAMMSpreadReserves = exports.calculateUpdatedAMM = exports.calculateNewAmm = exports.calculateOptimalPegAndBudget = exports.calculatePegFromTargetPrice = void 0;
|
|
4
4
|
const anchor_1 = require("@project-serum/anchor");
|
|
5
5
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
6
6
|
const types_1 = require("../types");
|
|
@@ -367,3 +367,15 @@ function calculateQuoteAssetAmountSwapped(quoteAssetReserves, pegMultiplier, swa
|
|
|
367
367
|
return quoteAssetAmount;
|
|
368
368
|
}
|
|
369
369
|
exports.calculateQuoteAssetAmountSwapped = calculateQuoteAssetAmountSwapped;
|
|
370
|
+
function calculateMaxBaseAssetAmountFillable(amm, orderDirection) {
|
|
371
|
+
const maxFillSize = amm.baseAssetReserve.div(new anchor_1.BN(amm.maxBaseAssetAmountRatio));
|
|
372
|
+
let maxBaseAssetAmountOnSide;
|
|
373
|
+
if ((0, types_1.isVariant)(orderDirection, 'long')) {
|
|
374
|
+
maxBaseAssetAmountOnSide = anchor_1.BN.max(numericConstants_1.ZERO, amm.maxBaseAssetReserve.sub(amm.baseAssetReserve));
|
|
375
|
+
}
|
|
376
|
+
else {
|
|
377
|
+
maxBaseAssetAmountOnSide = anchor_1.BN.max(numericConstants_1.ZERO, amm.baseAssetReserve.sub(amm.minBaseAssetReserve));
|
|
378
|
+
}
|
|
379
|
+
return (0, __1.standardizeBaseAssetAmount)(anchor_1.BN.min(maxFillSize, maxBaseAssetAmountOnSide), amm.baseAssetAmountStepSize);
|
|
380
|
+
}
|
|
381
|
+
exports.calculateMaxBaseAssetAmountFillable = calculateMaxBaseAssetAmountFillable;
|
package/lib/math/market.d.ts
CHANGED
|
@@ -27,5 +27,5 @@ export declare function calculateNewMarketAfterTrade(baseAssetAmount: BN, direct
|
|
|
27
27
|
export declare function calculateMarkOracleSpread(market: MarketAccount, oraclePriceData: OraclePriceData): BN;
|
|
28
28
|
export declare function calculateOracleSpread(price: BN, oraclePriceData: OraclePriceData): BN;
|
|
29
29
|
export declare function calculateMarketMarginRatio(market: MarketAccount, size: BN, marginCategory: MarginCategory): number;
|
|
30
|
-
export declare function
|
|
30
|
+
export declare function calculateUnrealizedAssetWeight(market: MarketAccount, unrealizedPnl: BN, marginCategory: MarginCategory): BN;
|
|
31
31
|
export declare function calculateMarketAvailablePNL(market: MarketAccount, bank: BankAccount): BN;
|
package/lib/math/market.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.calculateMarketAvailablePNL = exports.
|
|
3
|
+
exports.calculateMarketAvailablePNL = exports.calculateUnrealizedAssetWeight = exports.calculateMarketMarginRatio = exports.calculateOracleSpread = exports.calculateMarkOracleSpread = exports.calculateNewMarketAfterTrade = exports.calculateAskPrice = exports.calculateBidPrice = exports.calculateMarkPrice = void 0;
|
|
4
4
|
const anchor_1 = require("@project-serum/anchor");
|
|
5
5
|
const types_1 = require("../types");
|
|
6
6
|
const amm_1 = require("./amm");
|
|
@@ -72,19 +72,19 @@ function calculateMarketMarginRatio(market, size, marginCategory) {
|
|
|
72
72
|
return marginRatio;
|
|
73
73
|
}
|
|
74
74
|
exports.calculateMarketMarginRatio = calculateMarketMarginRatio;
|
|
75
|
-
function
|
|
75
|
+
function calculateUnrealizedAssetWeight(market, unrealizedPnl, marginCategory) {
|
|
76
76
|
let assetWeight;
|
|
77
77
|
switch (marginCategory) {
|
|
78
78
|
case 'Initial':
|
|
79
|
-
assetWeight = (0, margin_1.calculateSizeDiscountAssetWeight)(
|
|
79
|
+
assetWeight = (0, margin_1.calculateSizeDiscountAssetWeight)(unrealizedPnl, market.unrealizedImfFactor, new anchor_1.BN(market.unrealizedInitialAssetWeight));
|
|
80
80
|
break;
|
|
81
81
|
case 'Maintenance':
|
|
82
|
-
assetWeight = new anchor_1.BN(market.
|
|
82
|
+
assetWeight = new anchor_1.BN(market.unrealizedMaintenanceAssetWeight);
|
|
83
83
|
break;
|
|
84
84
|
}
|
|
85
85
|
return assetWeight;
|
|
86
86
|
}
|
|
87
|
-
exports.
|
|
87
|
+
exports.calculateUnrealizedAssetWeight = calculateUnrealizedAssetWeight;
|
|
88
88
|
function calculateMarketAvailablePNL(market, bank) {
|
|
89
89
|
return (0, bankBalance_1.getTokenAmount)(market.pnlPool.balance, bank, types_1.BankBalanceType.DEPOSIT);
|
|
90
90
|
}
|
package/lib/math/orders.d.ts
CHANGED
|
@@ -8,3 +8,6 @@ export declare function isOrderRiskIncreasingInSameDirection(user: ClearingHouse
|
|
|
8
8
|
export declare function isOrderReduceOnly(user: ClearingHouseUser, order: Order): boolean;
|
|
9
9
|
export declare function standardizeBaseAssetAmount(baseAssetAmount: BN, stepSize: BN): BN;
|
|
10
10
|
export declare function getLimitPrice(order: Order, market: MarketAccount, oraclePriceData: OraclePriceData, slot: number): BN;
|
|
11
|
+
export declare function isFillableByVAMM(order: Order, market: MarketAccount, oraclePriceData: OraclePriceData, slot: number): boolean;
|
|
12
|
+
export declare function calculateBaseAssetAmountForAmmToFulfill(order: Order, market: MarketAccount, oraclePriceData: OraclePriceData, slot: number): BN;
|
|
13
|
+
export declare function calculateBaseAssetAmountToFillUpToLimitPrice(order: Order, market: MarketAccount, limitPrice: BN, oraclePriceData: OraclePriceData): BN;
|
package/lib/math/orders.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getLimitPrice = exports.standardizeBaseAssetAmount = exports.isOrderReduceOnly = exports.isOrderRiskIncreasingInSameDirection = exports.isOrderRiskIncreasing = void 0;
|
|
3
|
+
exports.calculateBaseAssetAmountToFillUpToLimitPrice = exports.calculateBaseAssetAmountForAmmToFulfill = exports.isFillableByVAMM = exports.getLimitPrice = exports.standardizeBaseAssetAmount = exports.isOrderReduceOnly = exports.isOrderRiskIncreasingInSameDirection = exports.isOrderRiskIncreasing = void 0;
|
|
4
4
|
const types_1 = require("../types");
|
|
5
5
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
6
6
|
const anchor_1 = require("@project-serum/anchor");
|
|
7
7
|
const auction_1 = require("./auction");
|
|
8
8
|
const market_1 = require("./market");
|
|
9
|
+
const amm_1 = require("./amm");
|
|
9
10
|
function isOrderRiskIncreasing(user, order) {
|
|
10
11
|
if ((0, types_1.isVariant)(order.status, 'init')) {
|
|
11
12
|
return false;
|
|
@@ -108,3 +109,36 @@ function getLimitPrice(order, market, oraclePriceData, slot) {
|
|
|
108
109
|
return limitPrice;
|
|
109
110
|
}
|
|
110
111
|
exports.getLimitPrice = getLimitPrice;
|
|
112
|
+
function isFillableByVAMM(order, market, oraclePriceData, slot) {
|
|
113
|
+
return ((0, auction_1.isAuctionComplete)(order, slot) &&
|
|
114
|
+
!calculateBaseAssetAmountForAmmToFulfill(order, market, oraclePriceData, slot).eq(numericConstants_1.ZERO));
|
|
115
|
+
}
|
|
116
|
+
exports.isFillableByVAMM = isFillableByVAMM;
|
|
117
|
+
function calculateBaseAssetAmountForAmmToFulfill(order, market, oraclePriceData, slot) {
|
|
118
|
+
if ((0, types_1.isOneOfVariant)(order.orderType, ['triggerMarket', 'triggerLimit']) &&
|
|
119
|
+
order.triggered === false) {
|
|
120
|
+
return numericConstants_1.ZERO;
|
|
121
|
+
}
|
|
122
|
+
const limitPrice = getLimitPrice(order, market, oraclePriceData, slot);
|
|
123
|
+
const baseAssetAmount = calculateBaseAssetAmountToFillUpToLimitPrice(order, market, limitPrice, oraclePriceData);
|
|
124
|
+
const maxBaseAssetAmount = (0, amm_1.calculateMaxBaseAssetAmountFillable)(market.amm, order.direction);
|
|
125
|
+
return anchor_1.BN.min(maxBaseAssetAmount, baseAssetAmount);
|
|
126
|
+
}
|
|
127
|
+
exports.calculateBaseAssetAmountForAmmToFulfill = calculateBaseAssetAmountForAmmToFulfill;
|
|
128
|
+
function calculateBaseAssetAmountToFillUpToLimitPrice(order, market, limitPrice, oraclePriceData) {
|
|
129
|
+
const [maxAmountToTrade, direction] = (0, amm_1.calculateMaxBaseAssetAmountToTrade)(market.amm, limitPrice, order.direction, oraclePriceData);
|
|
130
|
+
const baseAssetAmount = standardizeBaseAssetAmount(maxAmountToTrade, market.amm.baseAssetAmountStepSize);
|
|
131
|
+
// Check that directions are the same
|
|
132
|
+
const sameDirection = isSameDirection(direction, order.direction);
|
|
133
|
+
if (!sameDirection) {
|
|
134
|
+
return numericConstants_1.ZERO;
|
|
135
|
+
}
|
|
136
|
+
return baseAssetAmount.gt(order.baseAssetAmount)
|
|
137
|
+
? order.baseAssetAmount
|
|
138
|
+
: baseAssetAmount;
|
|
139
|
+
}
|
|
140
|
+
exports.calculateBaseAssetAmountToFillUpToLimitPrice = calculateBaseAssetAmountToFillUpToLimitPrice;
|
|
141
|
+
function isSameDirection(firstDirection, secondDirection) {
|
|
142
|
+
return (((0, types_1.isVariant)(firstDirection, 'long') && (0, types_1.isVariant)(secondDirection, 'long')) ||
|
|
143
|
+
((0, types_1.isVariant)(firstDirection, 'short') && (0, types_1.isVariant)(secondDirection, 'short')));
|
|
144
|
+
}
|
package/lib/types.d.ts
CHANGED
|
@@ -136,6 +136,14 @@ export declare enum TradeSide {
|
|
|
136
136
|
Sell = 2
|
|
137
137
|
}
|
|
138
138
|
export declare type CandleResolution = '1' | '5' | '15' | '60' | '240' | 'D' | 'W' | 'M';
|
|
139
|
+
export declare type NewUserRecord = {
|
|
140
|
+
ts: BN;
|
|
141
|
+
userAuthority: PublicKey;
|
|
142
|
+
user: PublicKey;
|
|
143
|
+
userId: number;
|
|
144
|
+
name: number[];
|
|
145
|
+
referrer: PublicKey;
|
|
146
|
+
};
|
|
139
147
|
export declare type DepositRecord = {
|
|
140
148
|
ts: BN;
|
|
141
149
|
userAuthority: PublicKey;
|
|
@@ -147,6 +155,7 @@ export declare type DepositRecord = {
|
|
|
147
155
|
bankIndex: BN;
|
|
148
156
|
amount: BN;
|
|
149
157
|
oraclePrice: BN;
|
|
158
|
+
referrer: PublicKey;
|
|
150
159
|
from?: PublicKey;
|
|
151
160
|
to?: PublicKey;
|
|
152
161
|
};
|
|
@@ -303,6 +312,9 @@ export declare type OrderRecord = {
|
|
|
303
312
|
fillerReward: BN;
|
|
304
313
|
quoteAssetAmountSurplus: BN;
|
|
305
314
|
oraclePrice: BN;
|
|
315
|
+
referrer: PublicKey;
|
|
316
|
+
referrerReward: BN;
|
|
317
|
+
refereeDiscount: BN;
|
|
306
318
|
};
|
|
307
319
|
export declare type StateAccount = {
|
|
308
320
|
admin: PublicKey;
|
|
@@ -349,9 +361,9 @@ export declare type MarketAccount = {
|
|
|
349
361
|
pnlPool: PoolBalance;
|
|
350
362
|
liquidationFee: BN;
|
|
351
363
|
imfFactor: BN;
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
364
|
+
unrealizedImfFactor: BN;
|
|
365
|
+
unrealizedInitialAssetWeight: number;
|
|
366
|
+
unrealizedMaintenanceAssetWeight: number;
|
|
355
367
|
};
|
|
356
368
|
export declare type BankAccount = {
|
|
357
369
|
bankIndex: BN;
|
|
@@ -439,6 +451,8 @@ export declare type AMM = {
|
|
|
439
451
|
maxSpread: number;
|
|
440
452
|
marketPosition: UserPosition;
|
|
441
453
|
marketPositionPerLp: UserPosition;
|
|
454
|
+
maxBaseAssetReserve: BN;
|
|
455
|
+
minBaseAssetReserve: BN;
|
|
442
456
|
};
|
|
443
457
|
export declare type UserPosition = {
|
|
444
458
|
baseAssetAmount: BN;
|
|
@@ -467,11 +481,12 @@ export declare type UserStatsAccount = {
|
|
|
467
481
|
totalFeePaid: BN;
|
|
468
482
|
totalFeeRebate: BN;
|
|
469
483
|
totalTokenDiscount: BN;
|
|
470
|
-
totalReferralReward: BN;
|
|
471
484
|
totalRefereeDiscount: BN;
|
|
472
485
|
};
|
|
473
|
-
authority: PublicKey;
|
|
474
486
|
referrer: PublicKey;
|
|
487
|
+
isReferrer: boolean;
|
|
488
|
+
totalReferrerReward: BN;
|
|
489
|
+
authority: PublicKey;
|
|
475
490
|
};
|
|
476
491
|
export declare type UserAccount = {
|
|
477
492
|
authority: PublicKey;
|
|
@@ -483,6 +498,7 @@ export declare type UserAccount = {
|
|
|
483
498
|
beingLiquidated: boolean;
|
|
484
499
|
bankrupt: boolean;
|
|
485
500
|
nextLiquidationId: number;
|
|
501
|
+
nextOrderId: BN;
|
|
486
502
|
};
|
|
487
503
|
export declare type UserBankBalance = {
|
|
488
504
|
bankIndex: BN;
|
|
@@ -508,9 +524,7 @@ export declare type Order = {
|
|
|
508
524
|
triggerPrice: BN;
|
|
509
525
|
triggerCondition: OrderTriggerCondition;
|
|
510
526
|
triggered: boolean;
|
|
511
|
-
discountTier: OrderDiscountTier;
|
|
512
527
|
existingPositionDirection: PositionDirection;
|
|
513
|
-
referrer: PublicKey;
|
|
514
528
|
postOnly: boolean;
|
|
515
529
|
immediateOrCancel: boolean;
|
|
516
530
|
oraclePriceOffset: BN;
|
|
@@ -585,6 +599,10 @@ export declare type TakerInfo = {
|
|
|
585
599
|
takerStats: PublicKey;
|
|
586
600
|
order: Order;
|
|
587
601
|
};
|
|
602
|
+
export declare type ReferrerInfo = {
|
|
603
|
+
referrer: PublicKey;
|
|
604
|
+
referrerStats: PublicKey;
|
|
605
|
+
};
|
|
588
606
|
export interface IWallet {
|
|
589
607
|
signTransaction(tx: Transaction): Promise<Transaction>;
|
|
590
608
|
signAllTransactions(txs: Transaction[]): Promise<Transaction[]>;
|
package/package.json
CHANGED
package/src/clearingHouse.ts
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
OptionalOrderParams,
|
|
16
16
|
DefaultOrderParams,
|
|
17
17
|
OrderType,
|
|
18
|
+
ReferrerInfo,
|
|
18
19
|
} from './types';
|
|
19
20
|
import * as anchor from '@project-serum/anchor';
|
|
20
21
|
import clearingHouseIDL from './idl/clearing_house.json';
|
|
@@ -31,6 +32,7 @@ import {
|
|
|
31
32
|
LAMPORTS_PER_SOL,
|
|
32
33
|
Signer,
|
|
33
34
|
SystemProgram,
|
|
35
|
+
ComputeBudgetProgram,
|
|
34
36
|
} from '@solana/web3.js';
|
|
35
37
|
|
|
36
38
|
import { TokenFaucet } from './tokenFaucet';
|
|
@@ -50,7 +52,11 @@ import {
|
|
|
50
52
|
} from './accounts/types';
|
|
51
53
|
import { TxSender } from './tx/types';
|
|
52
54
|
import { wrapInTx } from './tx/utils';
|
|
53
|
-
import {
|
|
55
|
+
import {
|
|
56
|
+
ONE,
|
|
57
|
+
QUOTE_ASSET_BANK_INDEX,
|
|
58
|
+
ZERO,
|
|
59
|
+
} from './constants/numericConstants';
|
|
54
60
|
import { findDirectionToClose, positionIsAvailable } from './math/position';
|
|
55
61
|
import { getTokenAmount } from './math/bankBalance';
|
|
56
62
|
import { DEFAULT_USER_NAME, encodeName } from './userName';
|
|
@@ -340,10 +346,11 @@ export class ClearingHouse {
|
|
|
340
346
|
|
|
341
347
|
public async initializeUserAccount(
|
|
342
348
|
userId = 0,
|
|
343
|
-
name = DEFAULT_USER_NAME
|
|
349
|
+
name = DEFAULT_USER_NAME,
|
|
350
|
+
referrerInfo?: ReferrerInfo
|
|
344
351
|
): Promise<[TransactionSignature, PublicKey]> {
|
|
345
352
|
const [userAccountPublicKey, initializeUserAccountIx] =
|
|
346
|
-
await this.getInitializeUserInstructions(userId, name);
|
|
353
|
+
await this.getInitializeUserInstructions(userId, name, referrerInfo);
|
|
347
354
|
|
|
348
355
|
const tx = new Transaction();
|
|
349
356
|
if (userId === 0) {
|
|
@@ -357,7 +364,8 @@ export class ClearingHouse {
|
|
|
357
364
|
|
|
358
365
|
async getInitializeUserInstructions(
|
|
359
366
|
userId = 0,
|
|
360
|
-
name = DEFAULT_USER_NAME
|
|
367
|
+
name = DEFAULT_USER_NAME,
|
|
368
|
+
referrerInfo?: ReferrerInfo
|
|
361
369
|
): Promise<[PublicKey, TransactionInstruction]> {
|
|
362
370
|
const userAccountPublicKey = await getUserAccountPublicKey(
|
|
363
371
|
this.program.programId,
|
|
@@ -365,6 +373,20 @@ export class ClearingHouse {
|
|
|
365
373
|
userId
|
|
366
374
|
);
|
|
367
375
|
|
|
376
|
+
const remainingAccounts = new Array<AccountMeta>();
|
|
377
|
+
if (referrerInfo !== undefined) {
|
|
378
|
+
remainingAccounts.push({
|
|
379
|
+
pubkey: referrerInfo.referrer,
|
|
380
|
+
isWritable: true,
|
|
381
|
+
isSigner: false,
|
|
382
|
+
});
|
|
383
|
+
remainingAccounts.push({
|
|
384
|
+
pubkey: referrerInfo.referrerStats,
|
|
385
|
+
isWritable: true,
|
|
386
|
+
isSigner: false,
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
|
|
368
390
|
const nameBuffer = encodeName(name);
|
|
369
391
|
const initializeUserAccountIx =
|
|
370
392
|
await this.program.instruction.initializeUser(userId, nameBuffer, {
|
|
@@ -377,6 +399,7 @@ export class ClearingHouse {
|
|
|
377
399
|
systemProgram: anchor.web3.SystemProgram.programId,
|
|
378
400
|
state: await this.getStatePublicKey(),
|
|
379
401
|
},
|
|
402
|
+
remainingAccounts,
|
|
380
403
|
});
|
|
381
404
|
|
|
382
405
|
return [userAccountPublicKey, initializeUserAccountIx];
|
|
@@ -710,6 +733,7 @@ export class ClearingHouse {
|
|
|
710
733
|
bank: bank.pubkey,
|
|
711
734
|
bankVault: bank.vault,
|
|
712
735
|
user: userAccountPublicKey,
|
|
736
|
+
userStats: this.getUserStatsAccountPublicKey(),
|
|
713
737
|
userTokenAccount: userTokenAccount,
|
|
714
738
|
authority: this.wallet.publicKey,
|
|
715
739
|
tokenProgram: TOKEN_PROGRAM_ID,
|
|
@@ -841,10 +865,11 @@ export class ClearingHouse {
|
|
|
841
865
|
bankIndex = new BN(0),
|
|
842
866
|
userId = 0,
|
|
843
867
|
name = DEFAULT_USER_NAME,
|
|
844
|
-
fromUserId?: number
|
|
868
|
+
fromUserId?: number,
|
|
869
|
+
referrerInfo?: ReferrerInfo
|
|
845
870
|
): Promise<[TransactionSignature, PublicKey]> {
|
|
846
871
|
const [userAccountPublicKey, initializeUserAccountIx] =
|
|
847
|
-
await this.getInitializeUserInstructions(userId, name);
|
|
872
|
+
await this.getInitializeUserInstructions(userId, name, referrerInfo);
|
|
848
873
|
|
|
849
874
|
const additionalSigners: Array<Signer> = [];
|
|
850
875
|
|
|
@@ -919,7 +944,8 @@ export class ClearingHouse {
|
|
|
919
944
|
name = DEFAULT_USER_NAME,
|
|
920
945
|
bankIndex: BN,
|
|
921
946
|
tokenFaucet: TokenFaucet,
|
|
922
|
-
amount: BN
|
|
947
|
+
amount: BN,
|
|
948
|
+
referrerInfo?: ReferrerInfo
|
|
923
949
|
): Promise<[TransactionSignature, PublicKey]> {
|
|
924
950
|
const [associateTokenPublicKey, createAssociatedAccountIx, mintToIx] =
|
|
925
951
|
await tokenFaucet.createAssociatedTokenAccountAndMintToInstructions(
|
|
@@ -928,7 +954,7 @@ export class ClearingHouse {
|
|
|
928
954
|
);
|
|
929
955
|
|
|
930
956
|
const [userAccountPublicKey, initializeUserAccountIx] =
|
|
931
|
-
await this.getInitializeUserInstructions(userId, name);
|
|
957
|
+
await this.getInitializeUserInstructions(userId, name, referrerInfo);
|
|
932
958
|
|
|
933
959
|
const depositCollateralIx = await this.getDepositInstruction(
|
|
934
960
|
amount,
|
|
@@ -1037,6 +1063,7 @@ export class ClearingHouse {
|
|
|
1037
1063
|
bankVault: bank.vault,
|
|
1038
1064
|
bankVaultAuthority: bank.vaultAuthority,
|
|
1039
1065
|
user: userAccountPublicKey,
|
|
1066
|
+
userStats: this.getUserStatsAccountPublicKey(),
|
|
1040
1067
|
userTokenAccount: userTokenAccount,
|
|
1041
1068
|
authority: this.wallet.publicKey,
|
|
1042
1069
|
tokenProgram: TOKEN_PROGRAM_ID,
|
|
@@ -1088,6 +1115,7 @@ export class ClearingHouse {
|
|
|
1088
1115
|
authority: this.wallet.publicKey,
|
|
1089
1116
|
fromUser,
|
|
1090
1117
|
toUser,
|
|
1118
|
+
userStats: this.getUserStatsAccountPublicKey(),
|
|
1091
1119
|
state: await this.getStatePublicKey(),
|
|
1092
1120
|
},
|
|
1093
1121
|
remainingAccounts,
|
|
@@ -1400,11 +1428,18 @@ export class ClearingHouse {
|
|
|
1400
1428
|
userAccountPublicKey: PublicKey,
|
|
1401
1429
|
user: UserAccount,
|
|
1402
1430
|
order?: Order,
|
|
1403
|
-
makerInfo?: MakerInfo
|
|
1431
|
+
makerInfo?: MakerInfo,
|
|
1432
|
+
referrerInfo?: ReferrerInfo
|
|
1404
1433
|
): Promise<TransactionSignature> {
|
|
1405
1434
|
const { txSig } = await this.txSender.send(
|
|
1406
1435
|
wrapInTx(
|
|
1407
|
-
await this.getFillOrderIx(
|
|
1436
|
+
await this.getFillOrderIx(
|
|
1437
|
+
userAccountPublicKey,
|
|
1438
|
+
user,
|
|
1439
|
+
order,
|
|
1440
|
+
makerInfo,
|
|
1441
|
+
referrerInfo
|
|
1442
|
+
)
|
|
1408
1443
|
),
|
|
1409
1444
|
[],
|
|
1410
1445
|
this.opts
|
|
@@ -1416,7 +1451,8 @@ export class ClearingHouse {
|
|
|
1416
1451
|
userAccountPublicKey: PublicKey,
|
|
1417
1452
|
userAccount: UserAccount,
|
|
1418
1453
|
order: Order,
|
|
1419
|
-
makerInfo?: MakerInfo
|
|
1454
|
+
makerInfo?: MakerInfo,
|
|
1455
|
+
referrerInfo?: ReferrerInfo
|
|
1420
1456
|
): Promise<TransactionInstruction> {
|
|
1421
1457
|
const userStatsPublicKey = getUserStatsAccountPublicKey(
|
|
1422
1458
|
this.program.programId,
|
|
@@ -1426,7 +1462,11 @@ export class ClearingHouse {
|
|
|
1426
1462
|
const fillerPublicKey = await this.getUserAccountPublicKey();
|
|
1427
1463
|
const fillerStatsPublicKey = this.getUserStatsAccountPublicKey();
|
|
1428
1464
|
|
|
1429
|
-
const marketIndex = order
|
|
1465
|
+
const marketIndex = order
|
|
1466
|
+
? order.marketIndex
|
|
1467
|
+
: userAccount.orders.find((order) =>
|
|
1468
|
+
order.orderId.eq(userAccount.nextOrderId.sub(ONE))
|
|
1469
|
+
).marketIndex;
|
|
1430
1470
|
const marketAccount = this.getMarketAccount(marketIndex);
|
|
1431
1471
|
|
|
1432
1472
|
const oracleAccountMap = new Map<string, AccountMeta>();
|
|
@@ -1501,6 +1541,19 @@ export class ClearingHouse {
|
|
|
1501
1541
|
});
|
|
1502
1542
|
}
|
|
1503
1543
|
|
|
1544
|
+
if (referrerInfo) {
|
|
1545
|
+
remainingAccounts.push({
|
|
1546
|
+
pubkey: referrerInfo.referrer,
|
|
1547
|
+
isWritable: true,
|
|
1548
|
+
isSigner: false,
|
|
1549
|
+
});
|
|
1550
|
+
remainingAccounts.push({
|
|
1551
|
+
pubkey: referrerInfo.referrerStats,
|
|
1552
|
+
isWritable: true,
|
|
1553
|
+
isSigner: false,
|
|
1554
|
+
});
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1504
1557
|
const orderId = order.orderId;
|
|
1505
1558
|
const makerOrderId = makerInfo ? makerInfo.order.orderId : null;
|
|
1506
1559
|
|
|
@@ -1613,10 +1666,13 @@ export class ClearingHouse {
|
|
|
1613
1666
|
|
|
1614
1667
|
public async placeAndTake(
|
|
1615
1668
|
orderParams: OptionalOrderParams,
|
|
1616
|
-
makerInfo?: MakerInfo
|
|
1669
|
+
makerInfo?: MakerInfo,
|
|
1670
|
+
referrerInfo?: ReferrerInfo
|
|
1617
1671
|
): Promise<TransactionSignature> {
|
|
1618
1672
|
const { txSig, slot } = await this.txSender.send(
|
|
1619
|
-
wrapInTx(
|
|
1673
|
+
wrapInTx(
|
|
1674
|
+
await this.getPlaceAndTakeIx(orderParams, makerInfo, referrerInfo)
|
|
1675
|
+
),
|
|
1620
1676
|
[],
|
|
1621
1677
|
this.opts
|
|
1622
1678
|
);
|
|
@@ -1626,7 +1682,8 @@ export class ClearingHouse {
|
|
|
1626
1682
|
|
|
1627
1683
|
public async getPlaceAndTakeIx(
|
|
1628
1684
|
orderParams: OptionalOrderParams,
|
|
1629
|
-
makerInfo?: MakerInfo
|
|
1685
|
+
makerInfo?: MakerInfo,
|
|
1686
|
+
referrerInfo?: ReferrerInfo
|
|
1630
1687
|
): Promise<TransactionInstruction> {
|
|
1631
1688
|
orderParams = this.getOrderParams(orderParams);
|
|
1632
1689
|
const userStatsPublicKey = await this.getUserStatsAccountPublicKey();
|
|
@@ -1652,6 +1709,19 @@ export class ClearingHouse {
|
|
|
1652
1709
|
});
|
|
1653
1710
|
}
|
|
1654
1711
|
|
|
1712
|
+
if (referrerInfo) {
|
|
1713
|
+
remainingAccounts.push({
|
|
1714
|
+
pubkey: referrerInfo.referrer,
|
|
1715
|
+
isWritable: true,
|
|
1716
|
+
isSigner: false,
|
|
1717
|
+
});
|
|
1718
|
+
remainingAccounts.push({
|
|
1719
|
+
pubkey: referrerInfo.referrerStats,
|
|
1720
|
+
isWritable: true,
|
|
1721
|
+
isSigner: false,
|
|
1722
|
+
});
|
|
1723
|
+
}
|
|
1724
|
+
|
|
1655
1725
|
return await this.program.instruction.placeAndTake(
|
|
1656
1726
|
orderParams,
|
|
1657
1727
|
makerOrderId,
|
|
@@ -1669,10 +1739,13 @@ export class ClearingHouse {
|
|
|
1669
1739
|
|
|
1670
1740
|
public async placeAndMake(
|
|
1671
1741
|
orderParams: OptionalOrderParams,
|
|
1672
|
-
takerInfo: TakerInfo
|
|
1742
|
+
takerInfo: TakerInfo,
|
|
1743
|
+
referrerInfo?: ReferrerInfo
|
|
1673
1744
|
): Promise<TransactionSignature> {
|
|
1674
1745
|
const { txSig, slot } = await this.txSender.send(
|
|
1675
|
-
wrapInTx(
|
|
1746
|
+
wrapInTx(
|
|
1747
|
+
await this.getPlaceAndMakeIx(orderParams, takerInfo, referrerInfo)
|
|
1748
|
+
),
|
|
1676
1749
|
[],
|
|
1677
1750
|
this.opts
|
|
1678
1751
|
);
|
|
@@ -1684,7 +1757,8 @@ export class ClearingHouse {
|
|
|
1684
1757
|
|
|
1685
1758
|
public async getPlaceAndMakeIx(
|
|
1686
1759
|
orderParams: OptionalOrderParams,
|
|
1687
|
-
takerInfo: TakerInfo
|
|
1760
|
+
takerInfo: TakerInfo,
|
|
1761
|
+
referrerInfo?: ReferrerInfo
|
|
1688
1762
|
): Promise<TransactionInstruction> {
|
|
1689
1763
|
orderParams = this.getOrderParams(orderParams);
|
|
1690
1764
|
const userStatsPublicKey = this.getUserStatsAccountPublicKey();
|
|
@@ -1694,6 +1768,19 @@ export class ClearingHouse {
|
|
|
1694
1768
|
writableMarketIndex: orderParams.marketIndex,
|
|
1695
1769
|
});
|
|
1696
1770
|
|
|
1771
|
+
if (referrerInfo) {
|
|
1772
|
+
remainingAccounts.push({
|
|
1773
|
+
pubkey: referrerInfo.referrer,
|
|
1774
|
+
isWritable: true,
|
|
1775
|
+
isSigner: false,
|
|
1776
|
+
});
|
|
1777
|
+
remainingAccounts.push({
|
|
1778
|
+
pubkey: referrerInfo.referrerStats,
|
|
1779
|
+
isWritable: true,
|
|
1780
|
+
isSigner: false,
|
|
1781
|
+
});
|
|
1782
|
+
}
|
|
1783
|
+
|
|
1697
1784
|
const takerOrderId = takerInfo!.order!.orderId;
|
|
1698
1785
|
return await this.program.instruction.placeAndMake(
|
|
1699
1786
|
orderParams,
|
|
@@ -1754,7 +1841,14 @@ export class ClearingHouse {
|
|
|
1754
1841
|
);
|
|
1755
1842
|
}
|
|
1756
1843
|
|
|
1757
|
-
const tx = new Transaction()
|
|
1844
|
+
const tx = new Transaction()
|
|
1845
|
+
.add(
|
|
1846
|
+
ComputeBudgetProgram.requestUnits({
|
|
1847
|
+
units: 1_000_000,
|
|
1848
|
+
additionalFee: 0,
|
|
1849
|
+
})
|
|
1850
|
+
)
|
|
1851
|
+
.add(...ixs);
|
|
1758
1852
|
|
|
1759
1853
|
const { txSig } = await this.txSender.send(tx, [], this.opts);
|
|
1760
1854
|
return txSig;
|
package/src/clearingHouseUser.ts
CHANGED
|
@@ -33,7 +33,7 @@ import {
|
|
|
33
33
|
calculateBaseAssetValue,
|
|
34
34
|
calculatePositionFundingPNL,
|
|
35
35
|
calculatePositionPNL,
|
|
36
|
-
|
|
36
|
+
calculateUnrealizedAssetWeight,
|
|
37
37
|
calculateMarketMarginRatio,
|
|
38
38
|
PositionDirection,
|
|
39
39
|
calculateTradeSlippage,
|
|
@@ -372,11 +372,11 @@ export class ClearingHouseUser {
|
|
|
372
372
|
.positions.filter((pos) =>
|
|
373
373
|
marketIndex ? pos.marketIndex === marketIndex : true
|
|
374
374
|
)
|
|
375
|
-
.reduce((
|
|
375
|
+
.reduce((unrealizedPnl, marketPosition) => {
|
|
376
376
|
const market = this.clearingHouse.getMarketAccount(
|
|
377
377
|
marketPosition.marketIndex
|
|
378
378
|
);
|
|
379
|
-
let
|
|
379
|
+
let positionUnrealizedPnl = calculatePositionPNL(
|
|
380
380
|
market,
|
|
381
381
|
marketPosition,
|
|
382
382
|
withFunding,
|
|
@@ -384,12 +384,12 @@ export class ClearingHouseUser {
|
|
|
384
384
|
);
|
|
385
385
|
|
|
386
386
|
if (withWeightMarginCategory !== undefined) {
|
|
387
|
-
if (
|
|
388
|
-
|
|
387
|
+
if (positionUnrealizedPnl.gt(ZERO)) {
|
|
388
|
+
positionUnrealizedPnl = positionUnrealizedPnl
|
|
389
389
|
.mul(
|
|
390
|
-
|
|
390
|
+
calculateUnrealizedAssetWeight(
|
|
391
391
|
market,
|
|
392
|
-
|
|
392
|
+
positionUnrealizedPnl,
|
|
393
393
|
withWeightMarginCategory
|
|
394
394
|
)
|
|
395
395
|
)
|
|
@@ -397,7 +397,7 @@ export class ClearingHouseUser {
|
|
|
397
397
|
}
|
|
398
398
|
}
|
|
399
399
|
|
|
400
|
-
return
|
|
400
|
+
return unrealizedPnl.add(positionUnrealizedPnl);
|
|
401
401
|
}, ZERO);
|
|
402
402
|
}
|
|
403
403
|
|
|
@@ -528,47 +528,9 @@ export class ClearingHouseUser {
|
|
|
528
528
|
* @returns : Precision QUOTE_PRECISION
|
|
529
529
|
*/
|
|
530
530
|
public getTotalCollateral(marginCategory: MarginCategory = 'Initial'): BN {
|
|
531
|
-
return this.
|
|
532
|
-
.
|
|
533
|
-
|
|
534
|
-
bankBalance.balance.eq(ZERO) ||
|
|
535
|
-
isVariant(bankBalance.balanceType, 'borrow')
|
|
536
|
-
) {
|
|
537
|
-
return totalAssetValue;
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
// Todo this needs to account for whether it's based on initial or maintenance requirements
|
|
541
|
-
const bankAccount: BankAccount = this.clearingHouse.getBankAccount(
|
|
542
|
-
bankBalance.bankIndex
|
|
543
|
-
);
|
|
544
|
-
|
|
545
|
-
const tokenAmount = getTokenAmount(
|
|
546
|
-
bankBalance.balance,
|
|
547
|
-
bankAccount,
|
|
548
|
-
bankBalance.balanceType
|
|
549
|
-
);
|
|
550
|
-
|
|
551
|
-
const weight = calculateAssetWeight(
|
|
552
|
-
tokenAmount,
|
|
553
|
-
bankAccount,
|
|
554
|
-
marginCategory
|
|
555
|
-
);
|
|
556
|
-
|
|
557
|
-
return totalAssetValue.add(
|
|
558
|
-
tokenAmount
|
|
559
|
-
.mul(this.getOracleDataForBank(bankAccount.bankIndex).price)
|
|
560
|
-
.mul(weight)
|
|
561
|
-
.div(BANK_WEIGHT_PRECISION)
|
|
562
|
-
.div(MARK_PRICE_PRECISION)
|
|
563
|
-
// Adjust for decimals of bank account
|
|
564
|
-
.div(
|
|
565
|
-
new BN(10).pow(
|
|
566
|
-
new BN(bankAccount.decimals).sub(BANK_BALANCE_PRECISION_EXP)
|
|
567
|
-
)
|
|
568
|
-
)
|
|
569
|
-
);
|
|
570
|
-
}, ZERO)
|
|
571
|
-
.add(this.getUnrealizedPNL(true, undefined, marginCategory));
|
|
531
|
+
return this.getBankAssetValue(undefined, marginCategory).add(
|
|
532
|
+
this.getUnrealizedPNL(true, undefined, marginCategory)
|
|
533
|
+
);
|
|
572
534
|
}
|
|
573
535
|
|
|
574
536
|
/**
|