@drift-labs/sdk 2.49.0-beta.0 → 2.49.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/VERSION +1 -1
- package/lib/accounts/{mockUserAccountSubscriber.d.ts → basicUserAccountSubscriber.d.ts} +2 -2
- package/lib/accounts/{mockUserAccountSubscriber.js → basicUserAccountSubscriber.js} +9 -6
- package/lib/accounts/pollingInsuranceFundStakeAccountSubscriber.d.ts +29 -0
- package/lib/accounts/pollingInsuranceFundStakeAccountSubscriber.js +110 -0
- package/lib/accounts/types.d.ts +14 -1
- package/lib/accounts/webSocketInsuranceFundStakeAccountSubscriber.d.ts +23 -0
- package/lib/accounts/webSocketInsuranceFundStakeAccountSubscriber.js +65 -0
- package/lib/dlob/DLOB.d.ts +6 -2
- package/lib/dlob/DLOB.js +37 -12
- package/lib/driftClient.d.ts +66 -66
- package/lib/driftClient.js +208 -194
- package/lib/events/eventSubscriber.js +2 -1
- package/lib/events/sort.d.ts +2 -2
- package/lib/events/sort.js +6 -23
- package/lib/examples/loadDlob.js +10 -5
- package/lib/index.d.ts +3 -1
- package/lib/index.js +3 -1
- package/lib/math/auction.js +6 -1
- package/lib/orderSubscriber/OrderSubscriber.js +4 -0
- package/lib/orderSubscriber/WebsocketSubscription.d.ts +1 -1
- package/lib/orderSubscriber/WebsocketSubscription.js +8 -6
- package/lib/types.d.ts +0 -2
- package/lib/userMap/PollingSubscription.d.ts +15 -0
- package/lib/userMap/PollingSubscription.js +26 -0
- package/lib/userMap/WebsocketSubscription.d.ts +19 -0
- package/lib/userMap/WebsocketSubscription.js +40 -0
- package/lib/userMap/userMap.d.ts +15 -18
- package/lib/userMap/userMap.js +62 -31
- package/lib/userMap/userMapConfig.d.ts +20 -0
- package/lib/userMap/userMapConfig.js +2 -0
- package/package.json +1 -1
- package/src/accounts/{mockUserAccountSubscriber.ts → basicUserAccountSubscriber.ts} +8 -6
- package/src/accounts/pollingInsuranceFundStakeAccountSubscriber.ts +185 -0
- package/src/accounts/types.ts +21 -0
- package/src/accounts/webSocketInsuranceFundStakeAccountSubscriber.ts +127 -0
- package/src/dlob/DLOB.ts +55 -15
- package/src/driftClient.ts +429 -272
- package/src/events/eventSubscriber.ts +2 -1
- package/src/events/sort.ts +7 -29
- package/src/examples/loadDlob.ts +11 -6
- package/src/index.ts +3 -1
- package/src/math/auction.ts +8 -1
- package/src/orderSubscriber/OrderSubscriber.ts +4 -0
- package/src/orderSubscriber/WebsocketSubscription.ts +19 -16
- package/src/types.ts +0 -2
- package/src/userMap/PollingSubscription.ts +46 -0
- package/src/userMap/WebsocketSubscription.ts +74 -0
- package/src/userMap/userMap.ts +88 -60
- package/src/userMap/userMapConfig.ts +31 -0
- package/tests/amm/test.ts +6 -3
- package/tests/dlob/helpers.ts +2 -6
- package/tests/dlob/test.ts +194 -0
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.49.0-beta.
|
|
1
|
+
2.49.0-beta.10
|
|
@@ -4,14 +4,14 @@ import { PublicKey } from '@solana/web3.js';
|
|
|
4
4
|
import StrictEventEmitter from 'strict-event-emitter-types';
|
|
5
5
|
import { EventEmitter } from 'events';
|
|
6
6
|
import { UserAccount } from '../types';
|
|
7
|
-
export declare class
|
|
7
|
+
export declare class BasicUserAccountSubscriber implements UserAccountSubscriber {
|
|
8
8
|
isSubscribed: boolean;
|
|
9
9
|
eventEmitter: StrictEventEmitter<EventEmitter, UserAccountEvents>;
|
|
10
10
|
userAccountPublicKey: PublicKey;
|
|
11
11
|
callbackId?: string;
|
|
12
12
|
errorCallbackId?: string;
|
|
13
13
|
user: DataAndSlot<UserAccount>;
|
|
14
|
-
constructor(userAccountPublicKey: PublicKey, data
|
|
14
|
+
constructor(userAccountPublicKey: PublicKey, data?: UserAccount, slot?: number);
|
|
15
15
|
subscribe(_userAccount?: UserAccount): Promise<boolean>;
|
|
16
16
|
addToAccountLoader(): Promise<void>;
|
|
17
17
|
fetch(): Promise<void>;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.BasicUserAccountSubscriber = void 0;
|
|
4
4
|
const events_1 = require("events");
|
|
5
|
-
class
|
|
5
|
+
class BasicUserAccountSubscriber {
|
|
6
6
|
constructor(userAccountPublicKey, data, slot) {
|
|
7
7
|
this.isSubscribed = true;
|
|
8
8
|
this.eventEmitter = new events_1.EventEmitter();
|
|
@@ -23,9 +23,12 @@ class MockUserAccountSubscriber {
|
|
|
23
23
|
return this.user;
|
|
24
24
|
}
|
|
25
25
|
updateData(userAccount, slot) {
|
|
26
|
-
|
|
27
|
-
this.
|
|
28
|
-
|
|
26
|
+
var _a;
|
|
27
|
+
if (!this.user || slot >= ((_a = this.user.slot) !== null && _a !== void 0 ? _a : 0)) {
|
|
28
|
+
this.user = { data: userAccount, slot };
|
|
29
|
+
this.eventEmitter.emit('userAccountUpdate', userAccount);
|
|
30
|
+
this.eventEmitter.emit('update');
|
|
31
|
+
}
|
|
29
32
|
}
|
|
30
33
|
}
|
|
31
|
-
exports.
|
|
34
|
+
exports.BasicUserAccountSubscriber = BasicUserAccountSubscriber;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { DataAndSlot, InsuranceFundStakeAccountEvents, InsuranceFundStakeAccountSubscriber } from './types';
|
|
3
|
+
import { Program } from '@coral-xyz/anchor';
|
|
4
|
+
import StrictEventEmitter from 'strict-event-emitter-types';
|
|
5
|
+
import { EventEmitter } from 'events';
|
|
6
|
+
import { PublicKey } from '@solana/web3.js';
|
|
7
|
+
import { BulkAccountLoader } from './bulkAccountLoader';
|
|
8
|
+
import { InsuranceFundStake } from '../types';
|
|
9
|
+
export declare class PollingInsuranceFundStakeAccountSubscriber implements InsuranceFundStakeAccountSubscriber {
|
|
10
|
+
isSubscribed: boolean;
|
|
11
|
+
program: Program;
|
|
12
|
+
eventEmitter: StrictEventEmitter<EventEmitter, InsuranceFundStakeAccountEvents>;
|
|
13
|
+
insuranceFundStakeAccountPublicKey: PublicKey;
|
|
14
|
+
accountLoader: BulkAccountLoader;
|
|
15
|
+
callbackId?: string;
|
|
16
|
+
errorCallbackId?: string;
|
|
17
|
+
insuranceFundStakeAccountAndSlot?: DataAndSlot<InsuranceFundStake>;
|
|
18
|
+
constructor(program: Program, publicKey: PublicKey, accountLoader: BulkAccountLoader);
|
|
19
|
+
subscribe(insuranceFundStake?: InsuranceFundStake): Promise<boolean>;
|
|
20
|
+
addToAccountLoader(): Promise<void>;
|
|
21
|
+
fetchIfUnloaded(): Promise<void>;
|
|
22
|
+
fetch(): Promise<void>;
|
|
23
|
+
doesAccountExist(): boolean;
|
|
24
|
+
unsubscribe(): Promise<void>;
|
|
25
|
+
assertIsSubscribed(): void;
|
|
26
|
+
getInsuranceFundStakeAccountAndSlot(): DataAndSlot<InsuranceFundStake>;
|
|
27
|
+
didSubscriptionSucceed(): boolean;
|
|
28
|
+
updateData(insuranceFundStake: InsuranceFundStake, slot: number): void;
|
|
29
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PollingInsuranceFundStakeAccountSubscriber = void 0;
|
|
4
|
+
const types_1 = require("./types");
|
|
5
|
+
const events_1 = require("events");
|
|
6
|
+
class PollingInsuranceFundStakeAccountSubscriber {
|
|
7
|
+
constructor(program, publicKey, accountLoader) {
|
|
8
|
+
this.isSubscribed = false;
|
|
9
|
+
this.program = program;
|
|
10
|
+
this.insuranceFundStakeAccountPublicKey = publicKey;
|
|
11
|
+
this.accountLoader = accountLoader;
|
|
12
|
+
this.eventEmitter = new events_1.EventEmitter();
|
|
13
|
+
}
|
|
14
|
+
async subscribe(insuranceFundStake) {
|
|
15
|
+
if (this.isSubscribed) {
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
if (insuranceFundStake) {
|
|
19
|
+
this.insuranceFundStakeAccountAndSlot = {
|
|
20
|
+
data: insuranceFundStake,
|
|
21
|
+
slot: undefined,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
await this.addToAccountLoader();
|
|
25
|
+
if (this.doesAccountExist()) {
|
|
26
|
+
this.eventEmitter.emit('update');
|
|
27
|
+
}
|
|
28
|
+
this.isSubscribed = true;
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
async addToAccountLoader() {
|
|
32
|
+
if (this.callbackId) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
this.callbackId = await this.accountLoader.addAccount(this.insuranceFundStakeAccountPublicKey, (buffer, slot) => {
|
|
36
|
+
if (!buffer) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (this.insuranceFundStakeAccountAndSlot &&
|
|
40
|
+
this.insuranceFundStakeAccountAndSlot.slot > slot) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const account = this.program.account.user.coder.accounts.decode('InsuranceFundStake', buffer);
|
|
44
|
+
this.insuranceFundStakeAccountAndSlot = { data: account, slot };
|
|
45
|
+
this.eventEmitter.emit('insuranceFundStakeAccountUpdate', account);
|
|
46
|
+
this.eventEmitter.emit('update');
|
|
47
|
+
});
|
|
48
|
+
this.errorCallbackId = this.accountLoader.addErrorCallbacks((error) => {
|
|
49
|
+
this.eventEmitter.emit('error', error);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
async fetchIfUnloaded() {
|
|
53
|
+
if (this.insuranceFundStakeAccountAndSlot === undefined) {
|
|
54
|
+
await this.fetch();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
async fetch() {
|
|
58
|
+
var _a, _b;
|
|
59
|
+
try {
|
|
60
|
+
const dataAndContext = await this.program.account.insuranceFundStake.fetchAndContext(this.insuranceFundStakeAccountPublicKey, this.accountLoader.commitment);
|
|
61
|
+
if (dataAndContext.context.slot >
|
|
62
|
+
((_b = (_a = this.insuranceFundStakeAccountAndSlot) === null || _a === void 0 ? void 0 : _a.slot) !== null && _b !== void 0 ? _b : 0)) {
|
|
63
|
+
this.insuranceFundStakeAccountAndSlot = {
|
|
64
|
+
data: dataAndContext.data,
|
|
65
|
+
slot: dataAndContext.context.slot,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
catch (e) {
|
|
70
|
+
console.log(`PollingInsuranceFundStakeAccountSubscriber.fetch() InsuranceFundStake does not exist: ${e.message}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
doesAccountExist() {
|
|
74
|
+
return this.insuranceFundStakeAccountAndSlot !== undefined;
|
|
75
|
+
}
|
|
76
|
+
async unsubscribe() {
|
|
77
|
+
if (!this.isSubscribed) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
this.accountLoader.removeAccount(this.insuranceFundStakeAccountPublicKey, this.callbackId);
|
|
81
|
+
this.callbackId = undefined;
|
|
82
|
+
this.accountLoader.removeErrorCallbacks(this.errorCallbackId);
|
|
83
|
+
this.errorCallbackId = undefined;
|
|
84
|
+
this.isSubscribed = false;
|
|
85
|
+
}
|
|
86
|
+
assertIsSubscribed() {
|
|
87
|
+
if (!this.isSubscribed) {
|
|
88
|
+
throw new types_1.NotSubscribedError('You must call `subscribe` before using this function');
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
getInsuranceFundStakeAccountAndSlot() {
|
|
92
|
+
this.assertIsSubscribed();
|
|
93
|
+
return this.insuranceFundStakeAccountAndSlot;
|
|
94
|
+
}
|
|
95
|
+
didSubscriptionSucceed() {
|
|
96
|
+
return !!this.insuranceFundStakeAccountAndSlot;
|
|
97
|
+
}
|
|
98
|
+
updateData(insuranceFundStake, slot) {
|
|
99
|
+
if (!this.insuranceFundStakeAccountAndSlot ||
|
|
100
|
+
this.insuranceFundStakeAccountAndSlot.slot < slot) {
|
|
101
|
+
this.insuranceFundStakeAccountAndSlot = {
|
|
102
|
+
data: insuranceFundStake,
|
|
103
|
+
slot,
|
|
104
|
+
};
|
|
105
|
+
this.eventEmitter.emit('insuranceFundStakeAccountUpdate', insuranceFundStake);
|
|
106
|
+
this.eventEmitter.emit('update');
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
exports.PollingInsuranceFundStakeAccountSubscriber = PollingInsuranceFundStakeAccountSubscriber;
|
package/lib/accounts/types.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
/// <reference types="node" />
|
|
3
|
-
import { SpotMarketAccount, PerpMarketAccount, OracleSource, StateAccount, UserAccount, UserStatsAccount } from '../types';
|
|
3
|
+
import { SpotMarketAccount, PerpMarketAccount, OracleSource, StateAccount, UserAccount, UserStatsAccount, InsuranceFundStake } from '../types';
|
|
4
4
|
import StrictEventEmitter from 'strict-event-emitter-types';
|
|
5
5
|
import { EventEmitter } from 'events';
|
|
6
6
|
import { Context, PublicKey } from '@solana/web3.js';
|
|
@@ -73,6 +73,19 @@ export interface TokenAccountSubscriber {
|
|
|
73
73
|
unsubscribe(): Promise<void>;
|
|
74
74
|
getTokenAccountAndSlot(): DataAndSlot<Account>;
|
|
75
75
|
}
|
|
76
|
+
export interface InsuranceFundStakeAccountSubscriber {
|
|
77
|
+
eventEmitter: StrictEventEmitter<EventEmitter, InsuranceFundStakeAccountEvents>;
|
|
78
|
+
isSubscribed: boolean;
|
|
79
|
+
subscribe(): Promise<boolean>;
|
|
80
|
+
fetch(): Promise<void>;
|
|
81
|
+
unsubscribe(): Promise<void>;
|
|
82
|
+
getInsuranceFundStakeAccountAndSlot(): DataAndSlot<InsuranceFundStake>;
|
|
83
|
+
}
|
|
84
|
+
export interface InsuranceFundStakeAccountEvents {
|
|
85
|
+
insuranceFundStakeAccountUpdate: (payload: InsuranceFundStake) => void;
|
|
86
|
+
update: void;
|
|
87
|
+
error: (e: Error) => void;
|
|
88
|
+
}
|
|
76
89
|
export interface OracleEvents {
|
|
77
90
|
oracleUpdate: (payload: OraclePriceData) => void;
|
|
78
91
|
update: void;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { DataAndSlot, AccountSubscriber, InsuranceFundStakeAccountEvents, InsuranceFundStakeAccountSubscriber } from './types';
|
|
3
|
+
import { Program } from '@coral-xyz/anchor';
|
|
4
|
+
import StrictEventEmitter from 'strict-event-emitter-types';
|
|
5
|
+
import { EventEmitter } from 'events';
|
|
6
|
+
import { Commitment, PublicKey } from '@solana/web3.js';
|
|
7
|
+
import { InsuranceFundStake } from '../types';
|
|
8
|
+
export declare class WebSocketInsuranceFundStakeAccountSubscriber implements InsuranceFundStakeAccountSubscriber {
|
|
9
|
+
isSubscribed: boolean;
|
|
10
|
+
reconnectTimeoutMs?: number;
|
|
11
|
+
commitment?: Commitment;
|
|
12
|
+
program: Program;
|
|
13
|
+
eventEmitter: StrictEventEmitter<EventEmitter, InsuranceFundStakeAccountEvents>;
|
|
14
|
+
insuranceFundStakeAccountPublicKey: PublicKey;
|
|
15
|
+
insuranceFundStakeDataAccountSubscriber: AccountSubscriber<InsuranceFundStake>;
|
|
16
|
+
constructor(program: Program, insuranceFundStakeAccountPublicKey: PublicKey, reconnectTimeoutMs?: number, commitment?: Commitment);
|
|
17
|
+
subscribe(insuranceFundStakeAccount?: InsuranceFundStake): Promise<boolean>;
|
|
18
|
+
fetch(): Promise<void>;
|
|
19
|
+
unsubscribe(): Promise<void>;
|
|
20
|
+
assertIsSubscribed(): void;
|
|
21
|
+
getInsuranceFundStakeAccountAndSlot(): DataAndSlot<InsuranceFundStake>;
|
|
22
|
+
updateData(insuranceFundStake: InsuranceFundStake, slot: number): void;
|
|
23
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WebSocketInsuranceFundStakeAccountSubscriber = void 0;
|
|
4
|
+
const types_1 = require("./types");
|
|
5
|
+
const events_1 = require("events");
|
|
6
|
+
const webSocketAccountSubscriber_1 = require("./webSocketAccountSubscriber");
|
|
7
|
+
class WebSocketInsuranceFundStakeAccountSubscriber {
|
|
8
|
+
constructor(program, insuranceFundStakeAccountPublicKey, reconnectTimeoutMs, commitment) {
|
|
9
|
+
this.isSubscribed = false;
|
|
10
|
+
this.program = program;
|
|
11
|
+
this.insuranceFundStakeAccountPublicKey =
|
|
12
|
+
insuranceFundStakeAccountPublicKey;
|
|
13
|
+
this.eventEmitter = new events_1.EventEmitter();
|
|
14
|
+
this.reconnectTimeoutMs = reconnectTimeoutMs;
|
|
15
|
+
this.commitment = commitment;
|
|
16
|
+
}
|
|
17
|
+
async subscribe(insuranceFundStakeAccount) {
|
|
18
|
+
if (this.isSubscribed) {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
this.insuranceFundStakeDataAccountSubscriber =
|
|
22
|
+
new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('insuranceFundStake', this.program, this.insuranceFundStakeAccountPublicKey, undefined, this.reconnectTimeoutMs, this.commitment);
|
|
23
|
+
if (insuranceFundStakeAccount) {
|
|
24
|
+
this.insuranceFundStakeDataAccountSubscriber.setData(insuranceFundStakeAccount);
|
|
25
|
+
}
|
|
26
|
+
await this.insuranceFundStakeDataAccountSubscriber.subscribe((data) => {
|
|
27
|
+
this.eventEmitter.emit('insuranceFundStakeAccountUpdate', data);
|
|
28
|
+
this.eventEmitter.emit('update');
|
|
29
|
+
});
|
|
30
|
+
this.eventEmitter.emit('update');
|
|
31
|
+
this.isSubscribed = true;
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
async fetch() {
|
|
35
|
+
await Promise.all([this.insuranceFundStakeDataAccountSubscriber.fetch()]);
|
|
36
|
+
}
|
|
37
|
+
async unsubscribe() {
|
|
38
|
+
if (!this.isSubscribed) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
await Promise.all([
|
|
42
|
+
this.insuranceFundStakeDataAccountSubscriber.unsubscribe(),
|
|
43
|
+
]);
|
|
44
|
+
this.isSubscribed = false;
|
|
45
|
+
}
|
|
46
|
+
assertIsSubscribed() {
|
|
47
|
+
if (!this.isSubscribed) {
|
|
48
|
+
throw new types_1.NotSubscribedError('You must call `subscribe` before using this function');
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
getInsuranceFundStakeAccountAndSlot() {
|
|
52
|
+
this.assertIsSubscribed();
|
|
53
|
+
return this.insuranceFundStakeDataAccountSubscriber.dataAndSlot;
|
|
54
|
+
}
|
|
55
|
+
updateData(insuranceFundStake, slot) {
|
|
56
|
+
var _a;
|
|
57
|
+
const currentDataSlot = ((_a = this.insuranceFundStakeDataAccountSubscriber.dataAndSlot) === null || _a === void 0 ? void 0 : _a.slot) || 0;
|
|
58
|
+
if (currentDataSlot <= slot) {
|
|
59
|
+
this.insuranceFundStakeDataAccountSubscriber.setData(insuranceFundStake, slot);
|
|
60
|
+
this.eventEmitter.emit('insuranceFundStakeAccountUpdate', insuranceFundStake);
|
|
61
|
+
this.eventEmitter.emit('update');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
exports.WebSocketInsuranceFundStakeAccountSubscriber = WebSocketInsuranceFundStakeAccountSubscriber;
|
package/lib/dlob/DLOB.d.ts
CHANGED
|
@@ -68,11 +68,15 @@ export declare class DLOB {
|
|
|
68
68
|
updateRestingLimitOrdersForMarketType(slot: number, marketTypeStr: MarketTypeStr): void;
|
|
69
69
|
getOrder(orderId: number, userAccount: PublicKey): Order | undefined;
|
|
70
70
|
findNodesToFill(marketIndex: number, fallbackBid: BN | undefined, fallbackAsk: BN | undefined, slot: number, ts: number, marketType: MarketType, oraclePriceData: OraclePriceData, stateAccount: StateAccount, marketAccount: PerpMarketAccount | SpotMarketAccount): NodeToFill[];
|
|
71
|
+
getMakerRebate(marketType: MarketType, stateAccount: StateAccount, marketAccount: PerpMarketAccount | SpotMarketAccount): {
|
|
72
|
+
makerRebateNumerator: number;
|
|
73
|
+
makerRebateDenominator: number;
|
|
74
|
+
};
|
|
71
75
|
mergeNodesToFill(restingLimitOrderNodesToFill: NodeToFill[], takingOrderNodesToFill: NodeToFill[]): NodeToFill[];
|
|
72
|
-
findRestingLimitOrderNodesToFill(marketIndex: number, slot: number, marketType: MarketType, oraclePriceData: OraclePriceData, isAmmPaused: boolean, minAuctionDuration: number, fallbackAsk: BN | undefined, fallbackBid: BN | undefined): NodeToFill[];
|
|
76
|
+
findRestingLimitOrderNodesToFill(marketIndex: number, slot: number, marketType: MarketType, oraclePriceData: OraclePriceData, isAmmPaused: boolean, minAuctionDuration: number, makerRebateNumerator: number, makerRebateDenominator: number, fallbackAsk: BN | undefined, fallbackBid: BN | undefined): NodeToFill[];
|
|
73
77
|
findTakingNodesToFill(marketIndex: number, slot: number, marketType: MarketType, oraclePriceData: OraclePriceData, isAmmPaused: boolean, minAuctionDuration: number, fallbackAsk: BN | undefined, fallbackBid?: BN | undefined): NodeToFill[];
|
|
74
78
|
findTakingNodesCrossingMakerNodes(marketIndex: number, slot: number, marketType: MarketType, oraclePriceData: OraclePriceData, takerNodeGenerator: Generator<DLOBNode>, makerNodeGeneratorFn: (marketIndex: number, slot: number, marketType: MarketType, oraclePriceData: OraclePriceData) => Generator<DLOBNode>, doesCross: (takerPrice: BN | undefined, makerPrice: BN) => boolean): NodeToFill[];
|
|
75
|
-
findNodesCrossingFallbackLiquidity(marketType: MarketType, slot: number, oraclePriceData: OraclePriceData, nodeGenerator: Generator<DLOBNode>,
|
|
79
|
+
findNodesCrossingFallbackLiquidity(marketType: MarketType, slot: number, oraclePriceData: OraclePriceData, nodeGenerator: Generator<DLOBNode>, doesCross: (nodePrice: BN | undefined) => boolean, minAuctionDuration: number): NodeToFill[];
|
|
76
80
|
findExpiredNodesToFill(marketIndex: number, ts: number, marketType: MarketType): NodeToFill[];
|
|
77
81
|
findJitAuctionNodesToFill(marketIndex: number, slot: number, oraclePriceData: OraclePriceData, marketType: MarketType): NodeToFill[];
|
|
78
82
|
getTakingBids(marketIndex: number, marketType: MarketType, slot: number, oraclePriceData: OraclePriceData): Generator<DLOBNode>;
|
package/lib/dlob/DLOB.js
CHANGED
|
@@ -304,7 +304,8 @@ class DLOB {
|
|
|
304
304
|
const minAuctionDuration = (0, __1.isVariant)(marketType, 'perp')
|
|
305
305
|
? stateAccount.minPerpAuctionDuration
|
|
306
306
|
: 0;
|
|
307
|
-
const
|
|
307
|
+
const { makerRebateNumerator, makerRebateDenominator } = this.getMakerRebate(marketType, stateAccount, marketAccount);
|
|
308
|
+
const restingLimitOrderNodesToFill = this.findRestingLimitOrderNodesToFill(marketIndex, slot, marketType, oraclePriceData, isAmmPaused, minAuctionDuration, makerRebateNumerator, makerRebateDenominator, fallbackAsk, fallbackBid);
|
|
308
309
|
const takingOrderNodesToFill = this.findTakingNodesToFill(marketIndex, slot, marketType, oraclePriceData, isAmmPaused, minAuctionDuration, fallbackAsk, fallbackBid);
|
|
309
310
|
// get expired market nodes
|
|
310
311
|
const expiredNodesToFill = this.findExpiredNodesToFill(marketIndex, ts, marketType);
|
|
@@ -314,6 +315,28 @@ class DLOB {
|
|
|
314
315
|
}
|
|
315
316
|
return this.mergeNodesToFill(restingLimitOrderNodesToFill, takingOrderNodesToFill).concat(expiredNodesToFill);
|
|
316
317
|
}
|
|
318
|
+
getMakerRebate(marketType, stateAccount, marketAccount) {
|
|
319
|
+
let makerRebateNumerator;
|
|
320
|
+
let makerRebateDenominator;
|
|
321
|
+
if ((0, __1.isVariant)(marketType, 'perp')) {
|
|
322
|
+
makerRebateNumerator =
|
|
323
|
+
stateAccount.perpFeeStructure.feeTiers[0].makerRebateNumerator;
|
|
324
|
+
makerRebateDenominator =
|
|
325
|
+
stateAccount.perpFeeStructure.feeTiers[0].makerRebateDenominator;
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
makerRebateNumerator =
|
|
329
|
+
stateAccount.spotFeeStructure.feeTiers[0].makerRebateNumerator;
|
|
330
|
+
makerRebateDenominator =
|
|
331
|
+
stateAccount.spotFeeStructure.feeTiers[0].makerRebateDenominator;
|
|
332
|
+
}
|
|
333
|
+
// @ts-ignore
|
|
334
|
+
const feeAdjustment = marketAccount.feeAdjustment || 0;
|
|
335
|
+
if (feeAdjustment !== 0) {
|
|
336
|
+
makerRebateNumerator += (makerRebateNumerator * feeAdjustment) / 100;
|
|
337
|
+
}
|
|
338
|
+
return { makerRebateNumerator, makerRebateDenominator };
|
|
339
|
+
}
|
|
317
340
|
mergeNodesToFill(restingLimitOrderNodesToFill, takingOrderNodesToFill) {
|
|
318
341
|
const mergedNodesToFill = new Map();
|
|
319
342
|
const mergeNodesToFillHelper = (nodesToFillArray) => {
|
|
@@ -336,7 +359,7 @@ class DLOB {
|
|
|
336
359
|
mergeNodesToFillHelper(takingOrderNodesToFill);
|
|
337
360
|
return Array.from(mergedNodesToFill.values());
|
|
338
361
|
}
|
|
339
|
-
findRestingLimitOrderNodesToFill(marketIndex, slot, marketType, oraclePriceData, isAmmPaused, minAuctionDuration, fallbackAsk, fallbackBid) {
|
|
362
|
+
findRestingLimitOrderNodesToFill(marketIndex, slot, marketType, oraclePriceData, isAmmPaused, minAuctionDuration, makerRebateNumerator, makerRebateDenominator, fallbackAsk, fallbackBid) {
|
|
340
363
|
const nodesToFill = new Array();
|
|
341
364
|
const crossingNodes = this.findCrossingRestingLimitOrders(marketIndex, slot, marketType, oraclePriceData);
|
|
342
365
|
for (const crossingNode of crossingNodes) {
|
|
@@ -344,8 +367,9 @@ class DLOB {
|
|
|
344
367
|
}
|
|
345
368
|
if (fallbackBid && !isAmmPaused) {
|
|
346
369
|
const askGenerator = this.getRestingLimitAsks(marketIndex, slot, marketType, oraclePriceData);
|
|
347
|
-
const
|
|
348
|
-
|
|
370
|
+
const fallbackBidWithBuffer = fallbackBid.sub(fallbackBid.muln(makerRebateNumerator).divn(makerRebateDenominator));
|
|
371
|
+
const asksCrossingFallback = this.findNodesCrossingFallbackLiquidity(marketType, slot, oraclePriceData, askGenerator, (askPrice) => {
|
|
372
|
+
return askPrice.lte(fallbackBidWithBuffer);
|
|
349
373
|
}, minAuctionDuration);
|
|
350
374
|
for (const askCrossingFallback of asksCrossingFallback) {
|
|
351
375
|
nodesToFill.push(askCrossingFallback);
|
|
@@ -353,8 +377,9 @@ class DLOB {
|
|
|
353
377
|
}
|
|
354
378
|
if (fallbackAsk && !isAmmPaused) {
|
|
355
379
|
const bidGenerator = this.getRestingLimitBids(marketIndex, slot, marketType, oraclePriceData);
|
|
356
|
-
const
|
|
357
|
-
|
|
380
|
+
const fallbackAskWithBuffer = fallbackAsk.add(fallbackAsk.muln(makerRebateNumerator).divn(makerRebateDenominator));
|
|
381
|
+
const bidsCrossingFallback = this.findNodesCrossingFallbackLiquidity(marketType, slot, oraclePriceData, bidGenerator, (bidPrice) => {
|
|
382
|
+
return bidPrice.gte(fallbackAskWithBuffer);
|
|
358
383
|
}, minAuctionDuration);
|
|
359
384
|
for (const bidCrossingFallback of bidsCrossingFallback) {
|
|
360
385
|
nodesToFill.push(bidCrossingFallback);
|
|
@@ -381,8 +406,8 @@ class DLOB {
|
|
|
381
406
|
}
|
|
382
407
|
if (fallbackBid && !isAmmPaused) {
|
|
383
408
|
takingOrderGenerator = this.getTakingAsks(marketIndex, marketType, slot, oraclePriceData);
|
|
384
|
-
const takingAsksCrossingFallback = this.findNodesCrossingFallbackLiquidity(marketType, slot, oraclePriceData, takingOrderGenerator,
|
|
385
|
-
return takerPrice === undefined || takerPrice.lte(
|
|
409
|
+
const takingAsksCrossingFallback = this.findNodesCrossingFallbackLiquidity(marketType, slot, oraclePriceData, takingOrderGenerator, (takerPrice) => {
|
|
410
|
+
return takerPrice === undefined || takerPrice.lte(fallbackBid);
|
|
386
411
|
}, minAuctionDuration);
|
|
387
412
|
for (const takingAskCrossingFallback of takingAsksCrossingFallback) {
|
|
388
413
|
nodesToFill.push(takingAskCrossingFallback);
|
|
@@ -405,8 +430,8 @@ class DLOB {
|
|
|
405
430
|
}
|
|
406
431
|
if (fallbackAsk && !isAmmPaused) {
|
|
407
432
|
takingOrderGenerator = this.getTakingBids(marketIndex, marketType, slot, oraclePriceData);
|
|
408
|
-
const takingBidsCrossingFallback = this.findNodesCrossingFallbackLiquidity(marketType, slot, oraclePriceData, takingOrderGenerator,
|
|
409
|
-
return takerPrice === undefined || takerPrice.gte(
|
|
433
|
+
const takingBidsCrossingFallback = this.findNodesCrossingFallbackLiquidity(marketType, slot, oraclePriceData, takingOrderGenerator, (takerPrice) => {
|
|
434
|
+
return takerPrice === undefined || takerPrice.gte(fallbackAsk);
|
|
410
435
|
}, minAuctionDuration);
|
|
411
436
|
for (const marketBidCrossingFallback of takingBidsCrossingFallback) {
|
|
412
437
|
nodesToFill.push(marketBidCrossingFallback);
|
|
@@ -456,7 +481,7 @@ class DLOB {
|
|
|
456
481
|
}
|
|
457
482
|
return nodesToFill;
|
|
458
483
|
}
|
|
459
|
-
findNodesCrossingFallbackLiquidity(marketType, slot, oraclePriceData, nodeGenerator,
|
|
484
|
+
findNodesCrossingFallbackLiquidity(marketType, slot, oraclePriceData, nodeGenerator, doesCross, minAuctionDuration) {
|
|
460
485
|
var _a;
|
|
461
486
|
const nodesToFill = new Array();
|
|
462
487
|
let nextNode = nodeGenerator.next();
|
|
@@ -468,7 +493,7 @@ class DLOB {
|
|
|
468
493
|
}
|
|
469
494
|
const nodePrice = (0, __1.getLimitPrice)(node.order, oraclePriceData, slot);
|
|
470
495
|
// order crosses if there is no limit price or it crosses fallback price
|
|
471
|
-
const crosses = doesCross(nodePrice
|
|
496
|
+
const crosses = doesCross(nodePrice);
|
|
472
497
|
// fallback is available if auction is complete or it's a spot order
|
|
473
498
|
const fallbackAvailable = (0, __1.isVariant)(marketType, 'spot') ||
|
|
474
499
|
(0, __1.isFallbackAvailableLiquiditySource)(node.order, minAuctionDuration, slot);
|