@drift-labs/sdk 0.2.0-master.25 → 0.2.0-master.27
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/accounts/pollingClearingHouseAccountSubscriber.d.ts +14 -13
- package/lib/accounts/pollingClearingHouseAccountSubscriber.js +30 -27
- package/lib/accounts/types.d.ts +9 -9
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +15 -14
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +38 -34
- package/lib/addresses/pda.d.ts +7 -6
- package/lib/addresses/pda.js +31 -27
- package/lib/admin.d.ts +13 -7
- package/lib/admin.js +111 -44
- package/lib/clearingHouse.d.ts +71 -42
- package/lib/clearingHouse.js +767 -278
- package/lib/clearingHouseConfig.d.ts +2 -2
- package/lib/clearingHouseUser.d.ts +24 -22
- package/lib/clearingHouseUser.js +273 -177
- package/lib/config.d.ts +7 -7
- package/lib/config.js +21 -21
- package/lib/constants/numericConstants.d.ts +12 -12
- package/lib/constants/numericConstants.js +13 -13
- package/lib/constants/{markets.d.ts → perpMarkets.d.ts} +5 -5
- package/lib/constants/{markets.js → perpMarkets.js} +4 -4
- package/lib/constants/{banks.d.ts → spotMarkets.d.ts} +6 -6
- package/lib/constants/{banks.js → spotMarkets.js} +16 -16
- package/lib/dlob/DLOB.d.ts +73 -0
- package/lib/dlob/DLOB.js +557 -0
- package/lib/dlob/DLOBNode.d.ts +52 -0
- package/lib/dlob/DLOBNode.js +82 -0
- package/lib/dlob/NodeList.d.ts +26 -0
- package/lib/dlob/NodeList.js +138 -0
- package/lib/events/types.d.ts +2 -1
- package/lib/events/types.js +1 -0
- package/lib/examples/makeTradeExample.js +7 -7
- package/lib/idl/clearing_house.json +1152 -503
- package/lib/index.d.ts +10 -3
- package/lib/index.js +10 -3
- package/lib/math/amm.d.ts +2 -2
- package/lib/math/amm.js +1 -1
- package/lib/math/funding.d.ts +6 -6
- package/lib/math/funding.js +2 -1
- package/lib/math/margin.d.ts +4 -4
- package/lib/math/margin.js +18 -11
- package/lib/math/market.d.ts +11 -10
- package/lib/math/market.js +30 -7
- package/lib/math/oracles.d.ts +2 -1
- package/lib/math/oracles.js +11 -1
- package/lib/math/orders.d.ts +6 -6
- package/lib/math/orders.js +31 -16
- package/lib/math/position.d.ts +13 -13
- package/lib/math/position.js +19 -19
- package/lib/math/spotBalance.d.ts +22 -0
- package/lib/math/spotBalance.js +193 -0
- package/lib/math/spotMarket.d.ts +4 -0
- package/lib/math/spotMarket.js +8 -0
- package/lib/math/spotPosition.d.ts +6 -0
- package/lib/math/spotPosition.js +23 -0
- package/lib/math/state.js +2 -2
- package/lib/math/trade.d.ts +4 -4
- package/lib/orderParams.d.ts +4 -4
- package/lib/orderParams.js +12 -4
- package/lib/serum/serumSubscriber.d.ts +23 -0
- package/lib/serum/serumSubscriber.js +41 -0
- package/lib/serum/types.d.ts +11 -0
- package/lib/serum/types.js +2 -0
- package/lib/tx/retryTxSender.d.ts +1 -1
- package/lib/tx/retryTxSender.js +4 -2
- package/lib/tx/types.d.ts +1 -1
- package/lib/types.d.ts +148 -57
- package/lib/types.js +39 -11
- package/lib/userMap/userMap.d.ts +25 -0
- package/lib/userMap/userMap.js +73 -0
- package/lib/userMap/userStatsMap.d.ts +19 -0
- package/lib/userMap/userStatsMap.js +68 -0
- package/package.json +6 -3
- package/src/accounts/pollingClearingHouseAccountSubscriber.ts +42 -38
- package/src/accounts/types.ts +12 -9
- package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +65 -52
- package/src/addresses/pda.ts +49 -44
- package/src/admin.ts +190 -55
- package/src/clearingHouse.ts +1092 -365
- package/src/clearingHouseConfig.ts +2 -2
- package/src/clearingHouseUser.ts +518 -255
- package/src/config.ts +30 -30
- package/src/constants/numericConstants.ts +17 -15
- package/src/constants/{markets.ts → perpMarkets.ts} +5 -5
- package/src/constants/{banks.ts → spotMarkets.ts} +19 -19
- package/src/dlob/DLOB.ts +884 -0
- package/src/dlob/DLOBNode.ts +163 -0
- package/src/dlob/NodeList.ts +185 -0
- package/src/events/types.ts +3 -0
- package/src/examples/makeTradeExample.js +152 -75
- package/src/examples/makeTradeExample.ts +10 -8
- package/src/idl/clearing_house.json +1152 -503
- package/src/index.ts +10 -3
- package/src/math/amm.ts +6 -3
- package/src/math/funding.ts +7 -7
- package/src/math/margin.ts +34 -23
- package/src/math/market.ts +72 -20
- package/src/math/oracles.ts +18 -1
- package/src/math/orders.ts +33 -25
- package/src/math/position.ts +31 -31
- package/src/math/spotBalance.ts +316 -0
- package/src/math/spotMarket.ts +9 -0
- package/src/math/spotPosition.ts +47 -0
- package/src/math/state.ts +2 -2
- package/src/math/trade.ts +4 -4
- package/src/orderParams.ts +16 -8
- package/src/serum/serumSubscriber.ts +80 -0
- package/src/serum/types.ts +13 -0
- package/src/tx/retryTxSender.ts +5 -2
- package/src/tx/types.ts +2 -1
- package/src/types.ts +135 -56
- package/src/userMap/userMap.ts +100 -0
- package/src/userMap/userStatsMap.ts +110 -0
- package/tests/bn/test.ts +2 -3
- package/tests/dlob/helpers.ts +322 -0
- package/tests/dlob/test.ts +2865 -0
- package/lib/math/bankBalance.d.ts +0 -15
- package/lib/math/bankBalance.js +0 -150
- package/src/constants/numericConstants.js +0 -41
- package/src/math/bankBalance.ts +0 -258
- package/src/math/oracles.js +0 -26
- package/src/math/state.js +0 -15
- package/src/orderParams.js +0 -20
- package/src/slot/SlotSubscriber.js +0 -39
- package/src/tokenFaucet.js +0 -189
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { Connection, PublicKey } from '@solana/web3.js';
|
|
2
|
+
import { BulkAccountLoader } from '../accounts/bulkAccountLoader';
|
|
3
|
+
import { Market, Orderbook } from '@project-serum/serum';
|
|
4
|
+
import { SerumMarketSubscriberConfig } from './types';
|
|
5
|
+
|
|
6
|
+
export class SerumSubscriber {
|
|
7
|
+
connection: Connection;
|
|
8
|
+
programId: PublicKey;
|
|
9
|
+
marketAddress: PublicKey;
|
|
10
|
+
accountLoader: BulkAccountLoader;
|
|
11
|
+
market: Market;
|
|
12
|
+
|
|
13
|
+
subscribed: boolean;
|
|
14
|
+
|
|
15
|
+
asksAddress: PublicKey;
|
|
16
|
+
asks: Orderbook;
|
|
17
|
+
asksCallbackId: string;
|
|
18
|
+
lastAsksSlot: number;
|
|
19
|
+
|
|
20
|
+
bidsAddress: PublicKey;
|
|
21
|
+
bids: Orderbook;
|
|
22
|
+
bidsCallbackId: string;
|
|
23
|
+
lastBidsSlot: number;
|
|
24
|
+
|
|
25
|
+
public constructor(config: SerumMarketSubscriberConfig) {
|
|
26
|
+
this.connection = config.connection;
|
|
27
|
+
this.programId = config.programId;
|
|
28
|
+
this.marketAddress = config.marketAddress;
|
|
29
|
+
this.accountLoader = config.accountSubscription.accountLoader;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
public async subscribe(): Promise<void> {
|
|
33
|
+
if (this.subscribed) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
this.market = await Market.load(
|
|
38
|
+
this.connection,
|
|
39
|
+
this.marketAddress,
|
|
40
|
+
undefined,
|
|
41
|
+
this.programId
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
this.asksAddress = this.market.asksAddress;
|
|
45
|
+
this.asks = await this.market.loadAsks(this.connection);
|
|
46
|
+
|
|
47
|
+
this.asksCallbackId = this.accountLoader.addAccount(
|
|
48
|
+
this.asksAddress,
|
|
49
|
+
(buffer, slot) => {
|
|
50
|
+
this.lastAsksSlot = slot;
|
|
51
|
+
this.asks = Orderbook.decode(this.market, buffer);
|
|
52
|
+
console.log(this.asks.getL2(3));
|
|
53
|
+
}
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
this.bidsAddress = this.market.bidsAddress;
|
|
57
|
+
this.bids = await this.market.loadBids(this.connection);
|
|
58
|
+
|
|
59
|
+
this.bidsCallbackId = this.accountLoader.addAccount(
|
|
60
|
+
this.bidsAddress,
|
|
61
|
+
(buffer, slot) => {
|
|
62
|
+
this.lastBidsSlot = slot;
|
|
63
|
+
this.bids = Orderbook.decode(this.market, buffer);
|
|
64
|
+
}
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
this.subscribed = true;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
public async unsubscribe(): Promise<void> {
|
|
71
|
+
if (!this.subscribed) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
this.accountLoader.removeAccount(this.asksAddress, this.asksCallbackId);
|
|
76
|
+
this.accountLoader.removeAccount(this.bidsAddress, this.bidsCallbackId);
|
|
77
|
+
|
|
78
|
+
this.subscribed = false;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Connection, PublicKey } from '@solana/web3.js';
|
|
2
|
+
import { BulkAccountLoader } from '../accounts/bulkAccountLoader';
|
|
3
|
+
|
|
4
|
+
export type SerumMarketSubscriberConfig = {
|
|
5
|
+
connection: Connection;
|
|
6
|
+
programId: PublicKey;
|
|
7
|
+
marketAddress: PublicKey;
|
|
8
|
+
accountSubscription: {
|
|
9
|
+
// enables use to add web sockets in the future
|
|
10
|
+
type: 'polling';
|
|
11
|
+
accountLoader: BulkAccountLoader;
|
|
12
|
+
};
|
|
13
|
+
};
|
package/src/tx/retryTxSender.ts
CHANGED
|
@@ -42,7 +42,8 @@ export class RetryTxSender implements TxSender {
|
|
|
42
42
|
async send(
|
|
43
43
|
tx: Transaction,
|
|
44
44
|
additionalSigners?: Array<Signer>,
|
|
45
|
-
opts?: ConfirmOptions
|
|
45
|
+
opts?: ConfirmOptions,
|
|
46
|
+
preSigned?: boolean
|
|
46
47
|
): Promise<TxSigAndSlot> {
|
|
47
48
|
if (additionalSigners === undefined) {
|
|
48
49
|
additionalSigners = [];
|
|
@@ -51,7 +52,9 @@ export class RetryTxSender implements TxSender {
|
|
|
51
52
|
opts = this.provider.opts;
|
|
52
53
|
}
|
|
53
54
|
|
|
54
|
-
|
|
55
|
+
if (!preSigned) {
|
|
56
|
+
await this.prepareTx(tx, additionalSigners, opts);
|
|
57
|
+
}
|
|
55
58
|
|
|
56
59
|
const rawTransaction = tx.serialize();
|
|
57
60
|
const startTime = this.getTimestamp();
|
package/src/tx/types.ts
CHANGED
package/src/types.ts
CHANGED
|
@@ -2,12 +2,25 @@ import { PublicKey, Transaction } from '@solana/web3.js';
|
|
|
2
2
|
import { BN, ZERO } from '.';
|
|
3
3
|
|
|
4
4
|
// # Utility Types / Enums / Constants
|
|
5
|
+
|
|
6
|
+
export class MarketStatus {
|
|
7
|
+
static readonly INITIALIZED = { initialized: {} };
|
|
8
|
+
static readonly REDUCEONLY = { reduceonly: {} };
|
|
9
|
+
static readonly SETTLEMENT = { settlement: {} };
|
|
10
|
+
static readonly DELISTED = { delisted: {} };
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export class ContractType {
|
|
14
|
+
static readonly PERPETUAL = { perpetual: {} };
|
|
15
|
+
static readonly FUTURE = { future: {} };
|
|
16
|
+
}
|
|
17
|
+
|
|
5
18
|
export class SwapDirection {
|
|
6
19
|
static readonly ADD = { add: {} };
|
|
7
20
|
static readonly REMOVE = { remove: {} };
|
|
8
21
|
}
|
|
9
22
|
|
|
10
|
-
export class
|
|
23
|
+
export class SpotBalanceType {
|
|
11
24
|
static readonly DEPOSIT = { deposit: {} };
|
|
12
25
|
static readonly BORROW = { borrow: {} };
|
|
13
26
|
}
|
|
@@ -35,6 +48,12 @@ export class OrderType {
|
|
|
35
48
|
static readonly MARKET = { market: {} };
|
|
36
49
|
}
|
|
37
50
|
|
|
51
|
+
export declare type MarketTypeStr = 'perp' | 'spot';
|
|
52
|
+
export class MarketType {
|
|
53
|
+
static readonly SPOT = { spot: {} };
|
|
54
|
+
static readonly PERP = { perp: {} };
|
|
55
|
+
}
|
|
56
|
+
|
|
38
57
|
export class OrderStatus {
|
|
39
58
|
static readonly INIT = { init: {} };
|
|
40
59
|
static readonly OPEN = { open: {} };
|
|
@@ -77,6 +96,15 @@ export class OrderTriggerCondition {
|
|
|
77
96
|
static readonly BELOW = { below: {} };
|
|
78
97
|
}
|
|
79
98
|
|
|
99
|
+
export class SpotFulfillmentType {
|
|
100
|
+
static readonly SERUM_v3 = { serumV3: {} };
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export class SpotFulfillmentStatus {
|
|
104
|
+
static readonly ENABLED = { enabled: {} };
|
|
105
|
+
static readonly DISABLED = { disabled: {} };
|
|
106
|
+
}
|
|
107
|
+
|
|
80
108
|
export function isVariant(object: unknown, type: string) {
|
|
81
109
|
return object.hasOwnProperty(type);
|
|
82
110
|
}
|
|
@@ -87,6 +115,10 @@ export function isOneOfVariant(object: unknown, types: string[]) {
|
|
|
87
115
|
}, false);
|
|
88
116
|
}
|
|
89
117
|
|
|
118
|
+
export function getVariant(object: unknown): string {
|
|
119
|
+
return Object.keys(object)[0];
|
|
120
|
+
}
|
|
121
|
+
|
|
90
122
|
export enum TradeSide {
|
|
91
123
|
None = 0,
|
|
92
124
|
Buy = 1,
|
|
@@ -120,7 +152,7 @@ export type DepositRecord = {
|
|
|
120
152
|
deposit?: any;
|
|
121
153
|
withdraw?: any;
|
|
122
154
|
};
|
|
123
|
-
|
|
155
|
+
marketIndex: BN;
|
|
124
156
|
amount: BN;
|
|
125
157
|
oraclePrice: BN;
|
|
126
158
|
referrer: PublicKey;
|
|
@@ -148,6 +180,19 @@ export type CurveRecord = {
|
|
|
148
180
|
tradeId: BN;
|
|
149
181
|
};
|
|
150
182
|
|
|
183
|
+
export declare type InsuranceFundRecord = {
|
|
184
|
+
ts: BN;
|
|
185
|
+
bankIndex: BN;
|
|
186
|
+
marketIndex: BN;
|
|
187
|
+
userIfFactor: BN;
|
|
188
|
+
totalIfFactor: BN;
|
|
189
|
+
vaultAmountBefore: BN;
|
|
190
|
+
insuranceVaultAmountBefore: BN;
|
|
191
|
+
amount: BN;
|
|
192
|
+
totalIfSharesBefore: BN;
|
|
193
|
+
totalIfSharesAfter: BN;
|
|
194
|
+
};
|
|
195
|
+
|
|
151
196
|
export type LPRecord = {
|
|
152
197
|
ts: BN;
|
|
153
198
|
user: PublicKey;
|
|
@@ -202,6 +247,7 @@ export type LiquidationRecord = {
|
|
|
202
247
|
marginRequirement: BN;
|
|
203
248
|
totalCollateral: BN;
|
|
204
249
|
liquidationId: number;
|
|
250
|
+
canceledOrderIds: BN[];
|
|
205
251
|
liquidatePerp: LiquidatePerpRecord;
|
|
206
252
|
liquidateBorrow: LiquidateBorrowRecord;
|
|
207
253
|
liquidateBorrowForPerpPnl: LiquidateBorrowForPerpPnlRecord;
|
|
@@ -229,42 +275,42 @@ export class LiquidationType {
|
|
|
229
275
|
|
|
230
276
|
export type LiquidatePerpRecord = {
|
|
231
277
|
marketIndex: BN;
|
|
232
|
-
orderIds: BN[];
|
|
233
278
|
oraclePrice: BN;
|
|
234
279
|
baseAssetAmount: BN;
|
|
235
280
|
quoteAssetAmount: BN;
|
|
236
281
|
lpShares: BN;
|
|
237
282
|
userPnl: BN;
|
|
238
283
|
liquidatorPnl: BN;
|
|
239
|
-
canceledOrdersFee: BN;
|
|
240
284
|
userOrderId: BN;
|
|
241
285
|
liquidatorOrderId: BN;
|
|
242
286
|
fillRecordId: BN;
|
|
287
|
+
ifFee: BN;
|
|
243
288
|
};
|
|
244
289
|
|
|
245
290
|
export type LiquidateBorrowRecord = {
|
|
246
|
-
|
|
291
|
+
assetMarketIndex: BN;
|
|
247
292
|
assetPrice: BN;
|
|
248
293
|
assetTransfer: BN;
|
|
249
|
-
|
|
294
|
+
liabilityMarketIndex: BN;
|
|
250
295
|
liabilityPrice: BN;
|
|
251
296
|
liabilityTransfer: BN;
|
|
297
|
+
ifFee: BN;
|
|
252
298
|
};
|
|
253
299
|
|
|
254
300
|
export type LiquidateBorrowForPerpPnlRecord = {
|
|
255
|
-
|
|
301
|
+
perpMarketIndex: BN;
|
|
256
302
|
marketOraclePrice: BN;
|
|
257
303
|
pnlTransfer: BN;
|
|
258
|
-
|
|
304
|
+
liabilityMarketIndex: BN;
|
|
259
305
|
liabilityPrice: BN;
|
|
260
306
|
liabilityTransfer: BN;
|
|
261
307
|
};
|
|
262
308
|
|
|
263
309
|
export type LiquidatePerpPnlForDepositRecord = {
|
|
264
|
-
|
|
310
|
+
perpMarketIndex: BN;
|
|
265
311
|
marketOraclePrice: BN;
|
|
266
312
|
pnlTransfer: BN;
|
|
267
|
-
|
|
313
|
+
assetMarketIndex: BN;
|
|
268
314
|
assetPrice: BN;
|
|
269
315
|
assetTransfer: BN;
|
|
270
316
|
};
|
|
@@ -276,7 +322,7 @@ export type PerpBankruptcyRecord = {
|
|
|
276
322
|
};
|
|
277
323
|
|
|
278
324
|
export type BorrowBankruptcyRecord = {
|
|
279
|
-
|
|
325
|
+
marketIndex: BN;
|
|
280
326
|
borrowAmount: BN;
|
|
281
327
|
cumulativeDepositInterestDelta: BN;
|
|
282
328
|
};
|
|
@@ -288,7 +334,7 @@ export type SettlePnlRecord = {
|
|
|
288
334
|
pnl: BN;
|
|
289
335
|
baseAssetAmount: BN;
|
|
290
336
|
quoteAssetAmountAfter: BN;
|
|
291
|
-
|
|
337
|
+
quoteEntryAmount: BN;
|
|
292
338
|
settlePrice: BN;
|
|
293
339
|
};
|
|
294
340
|
|
|
@@ -318,12 +364,14 @@ export type OrderActionRecord = {
|
|
|
318
364
|
quoteAssetAmountSurplus: BN | null;
|
|
319
365
|
taker: PublicKey | null;
|
|
320
366
|
takerOrderId: BN | null;
|
|
367
|
+
takerOrderDirection: PositionDirection | null;
|
|
321
368
|
takerOrderBaseAssetAmount: BN | null;
|
|
322
369
|
takerOrderBaseAssetAmountFilled: BN | null;
|
|
323
370
|
takerOrderQuoteAssetAmountFilled: BN | null;
|
|
324
371
|
takerOrderFee: BN | null;
|
|
325
372
|
maker: PublicKey | null;
|
|
326
373
|
makerOrderId: BN | null;
|
|
374
|
+
makerOrderDirection: PositionDirection | null;
|
|
327
375
|
makerOrderBaseAssetAmount: BN | null;
|
|
328
376
|
makerOrderBaseAssetAmountFilled: BN | null;
|
|
329
377
|
makerOrderQuoteAssetAmountFilled: BN | null;
|
|
@@ -337,18 +385,8 @@ export type StateAccount = {
|
|
|
337
385
|
exchangePaused: boolean;
|
|
338
386
|
adminControlsPrices: boolean;
|
|
339
387
|
insuranceVault: PublicKey;
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
marginRatioPartial: BN;
|
|
343
|
-
partialLiquidationClosePercentageNumerator: BN;
|
|
344
|
-
partialLiquidationClosePercentageDenominator: BN;
|
|
345
|
-
partialLiquidationPenaltyPercentageNumerator: BN;
|
|
346
|
-
partialLiquidationPenaltyPercentageDenominator: BN;
|
|
347
|
-
fullLiquidationPenaltyPercentageNumerator: BN;
|
|
348
|
-
fullLiquidationPenaltyPercentageDenominator: BN;
|
|
349
|
-
partialLiquidationLiquidatorShareDenominator: BN;
|
|
350
|
-
fullLiquidationLiquidatorShareDenominator: BN;
|
|
351
|
-
feeStructure: FeeStructure;
|
|
388
|
+
perpFeeStructure: FeeStructure;
|
|
389
|
+
spotFeeStructure: FeeStructure;
|
|
352
390
|
totalFee: BN;
|
|
353
391
|
totalFeeWithdrawn: BN;
|
|
354
392
|
whitelistMint: PublicKey;
|
|
@@ -356,16 +394,21 @@ export type StateAccount = {
|
|
|
356
394
|
oracleGuardRails: OracleGuardRails;
|
|
357
395
|
maxDeposit: BN;
|
|
358
396
|
numberOfMarkets: BN;
|
|
359
|
-
|
|
397
|
+
numberOfSpotMarkets: BN;
|
|
360
398
|
minOrderQuoteAssetAmount: BN;
|
|
361
399
|
signer: PublicKey;
|
|
362
400
|
signerNonce: number;
|
|
363
|
-
|
|
364
|
-
|
|
401
|
+
defaultMarketOrderTimeInForce: number;
|
|
402
|
+
minPerpAuctionDuration: number;
|
|
403
|
+
defaultSpotAuctionDuration: number;
|
|
404
|
+
liquidationMarginBufferRatio: number;
|
|
365
405
|
};
|
|
366
406
|
|
|
367
|
-
export type
|
|
368
|
-
|
|
407
|
+
export type PerpMarketAccount = {
|
|
408
|
+
status: MarketStatus;
|
|
409
|
+
contractType: ContractType;
|
|
410
|
+
expiryTs: BN;
|
|
411
|
+
settlementPrice: BN;
|
|
369
412
|
marketIndex: BN;
|
|
370
413
|
pubkey: PublicKey;
|
|
371
414
|
amm: AMM;
|
|
@@ -377,15 +420,22 @@ export type MarketAccount = {
|
|
|
377
420
|
marginRatioMaintenance: number;
|
|
378
421
|
nextFillRecordId: BN;
|
|
379
422
|
pnlPool: PoolBalance;
|
|
380
|
-
|
|
423
|
+
liquidatorFee: BN;
|
|
424
|
+
ifLiquidationFee: BN;
|
|
381
425
|
imfFactor: BN;
|
|
382
426
|
unrealizedImfFactor: BN;
|
|
427
|
+
unrealizedMaxImbalance: BN;
|
|
383
428
|
unrealizedInitialAssetWeight: number;
|
|
384
429
|
unrealizedMaintenanceAssetWeight: number;
|
|
430
|
+
revenueWithdrawSinceLastSettle: BN;
|
|
431
|
+
maxRevenueWithdrawPerPeriod: BN;
|
|
432
|
+
lastRevenueWithdrawTs: BN;
|
|
433
|
+
quoteSettledInsurance: BN;
|
|
434
|
+
quoteMaxInsurance: BN;
|
|
385
435
|
};
|
|
386
436
|
|
|
387
|
-
export type
|
|
388
|
-
|
|
437
|
+
export type SpotMarketAccount = {
|
|
438
|
+
marketIndex: BN;
|
|
389
439
|
pubkey: PublicKey;
|
|
390
440
|
mint: PublicKey;
|
|
391
441
|
vault: PublicKey;
|
|
@@ -399,7 +449,7 @@ export type BankAccount = {
|
|
|
399
449
|
|
|
400
450
|
userIfFactor: BN;
|
|
401
451
|
totalIfFactor: BN;
|
|
402
|
-
|
|
452
|
+
ifLiquidationFee: BN;
|
|
403
453
|
|
|
404
454
|
decimals: number;
|
|
405
455
|
optimalUtilization: BN;
|
|
@@ -416,13 +466,20 @@ export type BankAccount = {
|
|
|
416
466
|
maintenanceAssetWeight: BN;
|
|
417
467
|
initialLiabilityWeight: BN;
|
|
418
468
|
maintenanceLiabilityWeight: BN;
|
|
419
|
-
|
|
469
|
+
liquidatorFee: BN;
|
|
420
470
|
imfFactor: BN;
|
|
421
471
|
|
|
422
472
|
withdrawGuardThreshold: BN;
|
|
423
473
|
depositTokenTwap: BN;
|
|
424
474
|
borrowTokenTwap: BN;
|
|
425
475
|
utilizationTwap: BN;
|
|
476
|
+
|
|
477
|
+
orderStepSize: BN;
|
|
478
|
+
nextFillRecordId: BN;
|
|
479
|
+
spotFeePool: {
|
|
480
|
+
balance: BN;
|
|
481
|
+
};
|
|
482
|
+
totalSpotFee: BN;
|
|
426
483
|
};
|
|
427
484
|
|
|
428
485
|
export type PoolBalance = {
|
|
@@ -477,21 +534,24 @@ export type AMM = {
|
|
|
477
534
|
totalMmFee: BN;
|
|
478
535
|
netRevenueSinceLastFunding: BN;
|
|
479
536
|
lastUpdateSlot: BN;
|
|
537
|
+
lastOracleValid: boolean;
|
|
480
538
|
lastBidPriceTwap: BN;
|
|
481
539
|
lastAskPriceTwap: BN;
|
|
482
540
|
longSpread: BN;
|
|
483
541
|
shortSpread: BN;
|
|
484
542
|
maxSpread: number;
|
|
485
|
-
marketPosition:
|
|
486
|
-
marketPositionPerLp:
|
|
543
|
+
marketPosition: PerpPosition;
|
|
544
|
+
marketPositionPerLp: PerpPosition;
|
|
487
545
|
ammJitIntensity: number;
|
|
488
546
|
maxBaseAssetReserve: BN;
|
|
489
547
|
minBaseAssetReserve: BN;
|
|
548
|
+
cumulativeSocialLoss: BN;
|
|
490
549
|
};
|
|
491
550
|
|
|
492
551
|
// # User Account Types
|
|
493
|
-
export type
|
|
552
|
+
export type PerpPosition = {
|
|
494
553
|
baseAssetAmount: BN;
|
|
554
|
+
remainderBaseAssetAmount: BN;
|
|
495
555
|
lastCumulativeFundingRate: BN;
|
|
496
556
|
marketIndex: BN;
|
|
497
557
|
quoteAssetAmount: BN;
|
|
@@ -531,24 +591,29 @@ export type UserAccount = {
|
|
|
531
591
|
authority: PublicKey;
|
|
532
592
|
name: number[];
|
|
533
593
|
userId: number;
|
|
534
|
-
|
|
535
|
-
|
|
594
|
+
spotPositions: SpotPosition[];
|
|
595
|
+
perpPositions: PerpPosition[];
|
|
536
596
|
orders: Order[];
|
|
537
597
|
beingLiquidated: boolean;
|
|
538
598
|
bankrupt: boolean;
|
|
539
599
|
nextLiquidationId: number;
|
|
540
600
|
nextOrderId: BN;
|
|
601
|
+
customMarginRatio: number;
|
|
541
602
|
};
|
|
542
603
|
|
|
543
|
-
export type
|
|
544
|
-
|
|
545
|
-
balanceType:
|
|
604
|
+
export type SpotPosition = {
|
|
605
|
+
marketIndex: BN;
|
|
606
|
+
balanceType: SpotBalanceType;
|
|
546
607
|
balance: BN;
|
|
608
|
+
openOrders: number;
|
|
609
|
+
openBids: BN;
|
|
610
|
+
openAsks: BN;
|
|
547
611
|
};
|
|
548
612
|
|
|
549
613
|
export type Order = {
|
|
550
614
|
status: OrderStatus;
|
|
551
615
|
orderType: OrderType;
|
|
616
|
+
marketType: MarketType;
|
|
552
617
|
ts: BN;
|
|
553
618
|
slot: BN;
|
|
554
619
|
orderId: BN;
|
|
@@ -572,10 +637,12 @@ export type Order = {
|
|
|
572
637
|
auctionDuration: number;
|
|
573
638
|
auctionStartPrice: BN;
|
|
574
639
|
auctionEndPrice: BN;
|
|
640
|
+
timeInForce: number;
|
|
575
641
|
};
|
|
576
642
|
|
|
577
643
|
export type OrderParams = {
|
|
578
644
|
orderType: OrderType;
|
|
645
|
+
marketType: MarketType;
|
|
579
646
|
userOrderId: number;
|
|
580
647
|
direction: PositionDirection;
|
|
581
648
|
baseAssetAmount: BN;
|
|
@@ -588,12 +655,9 @@ export type OrderParams = {
|
|
|
588
655
|
triggerCondition: OrderTriggerCondition;
|
|
589
656
|
positionLimit: BN;
|
|
590
657
|
oraclePriceOffset: BN;
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
discountToken: boolean;
|
|
595
|
-
referrer: boolean;
|
|
596
|
-
};
|
|
658
|
+
auctionDuration: number | null;
|
|
659
|
+
timeInForce: number | null;
|
|
660
|
+
auctionStartPrice: BN | null;
|
|
597
661
|
};
|
|
598
662
|
|
|
599
663
|
export type NecessaryOrderParams = {
|
|
@@ -609,6 +673,7 @@ export type OptionalOrderParams = {
|
|
|
609
673
|
|
|
610
674
|
export const DefaultOrderParams = {
|
|
611
675
|
orderType: OrderType.MARKET,
|
|
676
|
+
marketType: MarketType.PERP,
|
|
612
677
|
userOrderId: 0,
|
|
613
678
|
direction: PositionDirection.LONG,
|
|
614
679
|
baseAssetAmount: ZERO,
|
|
@@ -621,12 +686,9 @@ export const DefaultOrderParams = {
|
|
|
621
686
|
triggerCondition: OrderTriggerCondition.ABOVE,
|
|
622
687
|
positionLimit: ZERO,
|
|
623
688
|
oraclePriceOffset: ZERO,
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
discountToken: false,
|
|
628
|
-
referrer: false,
|
|
629
|
-
},
|
|
689
|
+
auctionDuration: null,
|
|
690
|
+
timeInForce: null,
|
|
691
|
+
auctionStartPrice: null,
|
|
630
692
|
};
|
|
631
693
|
|
|
632
694
|
export type MakerInfo = {
|
|
@@ -688,7 +750,7 @@ export type FeeStructure = {
|
|
|
688
750
|
makerRebateNumerator: BN;
|
|
689
751
|
makerRebateDenominator: BN;
|
|
690
752
|
fillerRewardStructure: OrderFillerRewardStructure;
|
|
691
|
-
|
|
753
|
+
flatFillerFee: BN;
|
|
692
754
|
};
|
|
693
755
|
|
|
694
756
|
export type OracleGuardRails = {
|
|
@@ -713,7 +775,7 @@ export type OrderFillerRewardStructure = {
|
|
|
713
775
|
export type MarginCategory = 'Initial' | 'Maintenance';
|
|
714
776
|
|
|
715
777
|
export type InsuranceFundStake = {
|
|
716
|
-
|
|
778
|
+
marketIndex: BN;
|
|
717
779
|
authority: PublicKey;
|
|
718
780
|
|
|
719
781
|
ifShares: BN;
|
|
@@ -723,3 +785,20 @@ export type InsuranceFundStake = {
|
|
|
723
785
|
lastWithdrawRequestValue: BN;
|
|
724
786
|
lastWithdrawRequestTs: BN;
|
|
725
787
|
};
|
|
788
|
+
|
|
789
|
+
export type SerumV3FulfillmentConfigAccount = {
|
|
790
|
+
fulfillmentType: SpotFulfillmentType;
|
|
791
|
+
status: SpotFulfillmentStatus;
|
|
792
|
+
pubkey: PublicKey;
|
|
793
|
+
marketIndex: BN;
|
|
794
|
+
serumProgramId: PublicKey;
|
|
795
|
+
serumMarket: PublicKey;
|
|
796
|
+
serumRequestQueue: PublicKey;
|
|
797
|
+
serumEventQueue: PublicKey;
|
|
798
|
+
serumBids: PublicKey;
|
|
799
|
+
serumAsks: PublicKey;
|
|
800
|
+
serumBaseVault: PublicKey;
|
|
801
|
+
serumQuoteVault: PublicKey;
|
|
802
|
+
serumOpenOrders: PublicKey;
|
|
803
|
+
serumSignerNonce: BN;
|
|
804
|
+
};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ClearingHouseUser,
|
|
3
|
+
ClearingHouse,
|
|
4
|
+
UserAccount,
|
|
5
|
+
bulkPollingUserSubscribe,
|
|
6
|
+
OrderRecord,
|
|
7
|
+
ClearingHouseUserAccountSubscriptionConfig,
|
|
8
|
+
} from '..';
|
|
9
|
+
import { ProgramAccount } from '@project-serum/anchor';
|
|
10
|
+
|
|
11
|
+
import { PublicKey } from '@solana/web3.js';
|
|
12
|
+
|
|
13
|
+
export class UserMap {
|
|
14
|
+
private userMap = new Map<string, ClearingHouseUser>();
|
|
15
|
+
private clearingHouse: ClearingHouse;
|
|
16
|
+
private accountSubscription: ClearingHouseUserAccountSubscriptionConfig;
|
|
17
|
+
|
|
18
|
+
constructor(
|
|
19
|
+
clearingHouse: ClearingHouse,
|
|
20
|
+
accountSubscription: ClearingHouseUserAccountSubscriptionConfig
|
|
21
|
+
) {
|
|
22
|
+
this.clearingHouse = clearingHouse;
|
|
23
|
+
this.accountSubscription = accountSubscription;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public async fetchAllUsers() {
|
|
27
|
+
const userArray: ClearingHouseUser[] = [];
|
|
28
|
+
|
|
29
|
+
const programUserAccounts =
|
|
30
|
+
(await this.clearingHouse.program.account.user.all()) as ProgramAccount<UserAccount>[];
|
|
31
|
+
for (const programUserAccount of programUserAccounts) {
|
|
32
|
+
if (this.userMap.has(programUserAccount.publicKey.toString())) {
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const user = new ClearingHouseUser({
|
|
37
|
+
clearingHouse: this.clearingHouse,
|
|
38
|
+
userAccountPublicKey: programUserAccount.publicKey,
|
|
39
|
+
accountSubscription: this.accountSubscription,
|
|
40
|
+
});
|
|
41
|
+
userArray.push(user);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (this.accountSubscription.type === 'polling') {
|
|
45
|
+
await bulkPollingUserSubscribe(
|
|
46
|
+
userArray,
|
|
47
|
+
this.accountSubscription.accountLoader
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
for (const user of userArray) {
|
|
52
|
+
this.userMap.set(user.getUserAccountPublicKey().toString(), user);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
public async addPubkey(userAccountPublicKey: PublicKey) {
|
|
57
|
+
const user = new ClearingHouseUser({
|
|
58
|
+
clearingHouse: this.clearingHouse,
|
|
59
|
+
userAccountPublicKey,
|
|
60
|
+
accountSubscription: this.accountSubscription,
|
|
61
|
+
});
|
|
62
|
+
await user.subscribe();
|
|
63
|
+
this.userMap.set(userAccountPublicKey.toString(), user);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
public has(key: string): boolean {
|
|
67
|
+
return this.userMap.has(key);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* gets the ClearingHouseUser for a particular userAccountPublicKey, if no ClearingHouseUser exists, undefined is returned
|
|
72
|
+
* @param key userAccountPublicKey to get ClearngHouseUserFor
|
|
73
|
+
* @returns user ClearingHouseUser | undefined
|
|
74
|
+
*/
|
|
75
|
+
public get(key: string): ClearingHouseUser | undefined {
|
|
76
|
+
return this.userMap.get(key);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* gets the ClearingHouseUser for a particular userAccountPublicKey, if no ClearingHouseUser exists, new one is created
|
|
81
|
+
* @param key userAccountPublicKey to get ClearngHouseUserFor
|
|
82
|
+
* @returns ClearingHouseUser
|
|
83
|
+
*/
|
|
84
|
+
public async mustGet(key: string): Promise<ClearingHouseUser> {
|
|
85
|
+
if (!this.has(key)) {
|
|
86
|
+
await this.addPubkey(new PublicKey(key));
|
|
87
|
+
}
|
|
88
|
+
const user = this.userMap.get(key);
|
|
89
|
+
await user.fetchAccounts();
|
|
90
|
+
return user;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
public async updateWithOrderRecord(record: OrderRecord) {
|
|
94
|
+
await this.addPubkey(record.user);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
public values(): IterableIterator<ClearingHouseUser> {
|
|
98
|
+
return this.userMap.values();
|
|
99
|
+
}
|
|
100
|
+
}
|