@drift-labs/sdk 2.52.0-beta.3 → 2.52.0-beta.5
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/examples/phoenix.ts +11 -4
- package/lib/orderSubscriber/OrderSubscriber.js +1 -0
- package/lib/orderSubscriber/WebsocketSubscription.d.ts +4 -1
- package/lib/orderSubscriber/WebsocketSubscription.js +25 -1
- package/lib/orderSubscriber/types.d.ts +1 -0
- package/lib/phoenix/phoenixSubscriber.js +10 -6
- package/package.json +1 -1
- package/src/orderSubscriber/OrderSubscriber.ts +1 -0
- package/src/orderSubscriber/WebsocketSubscription.ts +28 -0
- package/src/orderSubscriber/types.ts +1 -0
- package/src/phoenix/phoenixSubscriber.ts +14 -8
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.52.0-beta.
|
|
1
|
+
2.52.0-beta.5
|
package/examples/phoenix.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Connection, PublicKey } from '@solana/web3.js';
|
|
2
|
-
import { PRICE_PRECISION, PhoenixSubscriber } from '../src';
|
|
2
|
+
import { BASE_PRECISION, PRICE_PRECISION, PhoenixSubscriber } from '../src';
|
|
3
3
|
import { PROGRAM_ID } from '@ellipsis-labs/phoenix-sdk';
|
|
4
4
|
|
|
5
5
|
export async function listenToBook(): Promise<void> {
|
|
@@ -19,9 +19,16 @@ export async function listenToBook(): Promise<void> {
|
|
|
19
19
|
await phoenixSubscriber.subscribe();
|
|
20
20
|
|
|
21
21
|
for (let i = 0; i < 10; i++) {
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
console.log(
|
|
22
|
+
const bids = phoenixSubscriber.getL2Levels("bids");
|
|
23
|
+
const asks = phoenixSubscriber.getL2Levels("asks");
|
|
24
|
+
console.log("bids");
|
|
25
|
+
for (const bid of bids) {
|
|
26
|
+
console.log(bid.price.toNumber() / PRICE_PRECISION.toNumber(), bid.size.toNumber() / BASE_PRECISION.toNumber());
|
|
27
|
+
}
|
|
28
|
+
console.log("asks");
|
|
29
|
+
for (const ask of asks) {
|
|
30
|
+
console.log(ask.price.toNumber() / PRICE_PRECISION.toNumber(), ask.size.toNumber() / BASE_PRECISION.toNumber());
|
|
31
|
+
}
|
|
25
32
|
await new Promise((r) => setTimeout(r, 2000));
|
|
26
33
|
}
|
|
27
34
|
|
|
@@ -28,6 +28,7 @@ class OrderSubscriber {
|
|
|
28
28
|
commitment: this.commitment,
|
|
29
29
|
skipInitialLoad: config.subscriptionConfig.skipInitialLoad,
|
|
30
30
|
resubTimeoutMs: config.subscriptionConfig.resubTimeoutMs,
|
|
31
|
+
resyncIntervalMs: config.subscriptionConfig.resyncIntervalMs,
|
|
31
32
|
});
|
|
32
33
|
}
|
|
33
34
|
if ((_a = config.fastDecode) !== null && _a !== void 0 ? _a : true) {
|
|
@@ -5,12 +5,15 @@ export declare class WebsocketSubscription {
|
|
|
5
5
|
private commitment;
|
|
6
6
|
private skipInitialLoad;
|
|
7
7
|
private resubTimeoutMs?;
|
|
8
|
+
private resyncIntervalMs?;
|
|
8
9
|
private subscriber?;
|
|
9
|
-
|
|
10
|
+
private resyncTimeoutId?;
|
|
11
|
+
constructor({ orderSubscriber, commitment, skipInitialLoad, resubTimeoutMs, resyncIntervalMs, }: {
|
|
10
12
|
orderSubscriber: OrderSubscriber;
|
|
11
13
|
commitment: Commitment;
|
|
12
14
|
skipInitialLoad?: boolean;
|
|
13
15
|
resubTimeoutMs?: number;
|
|
16
|
+
resyncIntervalMs?: number;
|
|
14
17
|
});
|
|
15
18
|
subscribe(): Promise<void>;
|
|
16
19
|
unsubscribe(): Promise<void>;
|
|
@@ -4,11 +4,12 @@ exports.WebsocketSubscription = void 0;
|
|
|
4
4
|
const memcmp_1 = require("../memcmp");
|
|
5
5
|
const webSocketProgramAccountSubscriber_1 = require("../accounts/webSocketProgramAccountSubscriber");
|
|
6
6
|
class WebsocketSubscription {
|
|
7
|
-
constructor({ orderSubscriber, commitment, skipInitialLoad = false, resubTimeoutMs, }) {
|
|
7
|
+
constructor({ orderSubscriber, commitment, skipInitialLoad = false, resubTimeoutMs, resyncIntervalMs, }) {
|
|
8
8
|
this.orderSubscriber = orderSubscriber;
|
|
9
9
|
this.commitment = commitment;
|
|
10
10
|
this.skipInitialLoad = skipInitialLoad;
|
|
11
11
|
this.resubTimeoutMs = resubTimeoutMs;
|
|
12
|
+
this.resyncIntervalMs = resyncIntervalMs;
|
|
12
13
|
}
|
|
13
14
|
async subscribe() {
|
|
14
15
|
if (this.subscriber) {
|
|
@@ -25,12 +26,35 @@ class WebsocketSubscription {
|
|
|
25
26
|
if (!this.skipInitialLoad) {
|
|
26
27
|
await this.orderSubscriber.fetch();
|
|
27
28
|
}
|
|
29
|
+
if (this.resyncIntervalMs) {
|
|
30
|
+
const recursiveResync = () => {
|
|
31
|
+
this.resyncTimeoutId = setTimeout(() => {
|
|
32
|
+
this.orderSubscriber
|
|
33
|
+
.fetch()
|
|
34
|
+
.catch((e) => {
|
|
35
|
+
console.error('Failed to resync in OrderSubscriber');
|
|
36
|
+
console.log(e);
|
|
37
|
+
})
|
|
38
|
+
.finally(() => {
|
|
39
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
40
|
+
if (!this.resyncTimeoutId)
|
|
41
|
+
return;
|
|
42
|
+
recursiveResync();
|
|
43
|
+
});
|
|
44
|
+
}, this.resyncIntervalMs);
|
|
45
|
+
};
|
|
46
|
+
recursiveResync();
|
|
47
|
+
}
|
|
28
48
|
}
|
|
29
49
|
async unsubscribe() {
|
|
30
50
|
if (!this.subscriber)
|
|
31
51
|
return;
|
|
32
52
|
await this.subscriber.unsubscribe();
|
|
33
53
|
this.subscriber = undefined;
|
|
54
|
+
if (this.resyncTimeoutId !== undefined) {
|
|
55
|
+
clearTimeout(this.resyncTimeoutId);
|
|
56
|
+
this.resyncTimeoutId = undefined;
|
|
57
|
+
}
|
|
34
58
|
}
|
|
35
59
|
}
|
|
36
60
|
exports.WebsocketSubscription = WebsocketSubscription;
|
|
@@ -99,14 +99,18 @@ class PhoenixSubscriber {
|
|
|
99
99
|
return this.getL2Levels('asks');
|
|
100
100
|
}
|
|
101
101
|
*getL2Levels(side) {
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
const
|
|
102
|
+
const tickSize = this.market.data.header
|
|
103
|
+
.tickSizeInQuoteAtomsPerBaseUnit;
|
|
104
|
+
const baseLotsToRawBaseUnits = this.market.baseLotsToRawBaseUnits(1);
|
|
105
|
+
const basePrecision = new anchor_1.BN(Math.pow(10, this.market.data.header.baseParams.decimals) *
|
|
106
|
+
baseLotsToRawBaseUnits);
|
|
107
|
+
const pricePrecision = numericConstants_1.PRICE_PRECISION.div(tickSize);
|
|
108
|
+
const ladder = (0, phoenix_sdk_1.getMarketLadder)(this.market, this.lastSlot, this.lastUnixTimestamp, 20);
|
|
105
109
|
for (let i = 0; i < ladder[side].length; i++) {
|
|
106
|
-
const {
|
|
107
|
-
const size =
|
|
110
|
+
const { priceInTicks, sizeInBaseLots } = ladder[side][i];
|
|
111
|
+
const size = sizeInBaseLots.mul(basePrecision);
|
|
108
112
|
yield {
|
|
109
|
-
price:
|
|
113
|
+
price: priceInTicks.mul(new anchor_1.BN(pricePrecision)),
|
|
110
114
|
size,
|
|
111
115
|
sources: {
|
|
112
116
|
phoenix: size,
|
package/package.json
CHANGED
|
@@ -39,6 +39,7 @@ export class OrderSubscriber {
|
|
|
39
39
|
commitment: this.commitment,
|
|
40
40
|
skipInitialLoad: config.subscriptionConfig.skipInitialLoad,
|
|
41
41
|
resubTimeoutMs: config.subscriptionConfig.resubTimeoutMs,
|
|
42
|
+
resyncIntervalMs: config.subscriptionConfig.resyncIntervalMs,
|
|
42
43
|
});
|
|
43
44
|
}
|
|
44
45
|
if (config.fastDecode ?? true) {
|
|
@@ -9,24 +9,29 @@ export class WebsocketSubscription {
|
|
|
9
9
|
private commitment: Commitment;
|
|
10
10
|
private skipInitialLoad: boolean;
|
|
11
11
|
private resubTimeoutMs?: number;
|
|
12
|
+
private resyncIntervalMs?: number;
|
|
12
13
|
|
|
13
14
|
private subscriber?: WebSocketProgramAccountSubscriber<UserAccount>;
|
|
15
|
+
private resyncTimeoutId?: NodeJS.Timeout;
|
|
14
16
|
|
|
15
17
|
constructor({
|
|
16
18
|
orderSubscriber,
|
|
17
19
|
commitment,
|
|
18
20
|
skipInitialLoad = false,
|
|
19
21
|
resubTimeoutMs,
|
|
22
|
+
resyncIntervalMs,
|
|
20
23
|
}: {
|
|
21
24
|
orderSubscriber: OrderSubscriber;
|
|
22
25
|
commitment: Commitment;
|
|
23
26
|
skipInitialLoad?: boolean;
|
|
24
27
|
resubTimeoutMs?: number;
|
|
28
|
+
resyncIntervalMs?: number;
|
|
25
29
|
}) {
|
|
26
30
|
this.orderSubscriber = orderSubscriber;
|
|
27
31
|
this.commitment = commitment;
|
|
28
32
|
this.skipInitialLoad = skipInitialLoad;
|
|
29
33
|
this.resubTimeoutMs = resubTimeoutMs;
|
|
34
|
+
this.resyncIntervalMs = resyncIntervalMs;
|
|
30
35
|
}
|
|
31
36
|
|
|
32
37
|
public async subscribe(): Promise<void> {
|
|
@@ -61,11 +66,34 @@ export class WebsocketSubscription {
|
|
|
61
66
|
if (!this.skipInitialLoad) {
|
|
62
67
|
await this.orderSubscriber.fetch();
|
|
63
68
|
}
|
|
69
|
+
|
|
70
|
+
if (this.resyncIntervalMs) {
|
|
71
|
+
const recursiveResync = () => {
|
|
72
|
+
this.resyncTimeoutId = setTimeout(() => {
|
|
73
|
+
this.orderSubscriber
|
|
74
|
+
.fetch()
|
|
75
|
+
.catch((e) => {
|
|
76
|
+
console.error('Failed to resync in OrderSubscriber');
|
|
77
|
+
console.log(e);
|
|
78
|
+
})
|
|
79
|
+
.finally(() => {
|
|
80
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
81
|
+
if (!this.resyncTimeoutId) return;
|
|
82
|
+
recursiveResync();
|
|
83
|
+
});
|
|
84
|
+
}, this.resyncIntervalMs);
|
|
85
|
+
};
|
|
86
|
+
recursiveResync();
|
|
87
|
+
}
|
|
64
88
|
}
|
|
65
89
|
|
|
66
90
|
public async unsubscribe(): Promise<void> {
|
|
67
91
|
if (!this.subscriber) return;
|
|
68
92
|
await this.subscriber.unsubscribe();
|
|
69
93
|
this.subscriber = undefined;
|
|
94
|
+
if (this.resyncTimeoutId !== undefined) {
|
|
95
|
+
clearTimeout(this.resyncTimeoutId);
|
|
96
|
+
this.resyncTimeoutId = undefined;
|
|
97
|
+
}
|
|
70
98
|
}
|
|
71
99
|
}
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
toNum,
|
|
7
7
|
getMarketUiLadder,
|
|
8
8
|
Market,
|
|
9
|
+
getMarketLadder,
|
|
9
10
|
} from '@ellipsis-labs/phoenix-sdk';
|
|
10
11
|
import { PRICE_PRECISION } from '../constants/numericConstants';
|
|
11
12
|
import { BN } from '@coral-xyz/anchor';
|
|
@@ -163,13 +164,18 @@ export class PhoenixSubscriber implements L2OrderBookGenerator {
|
|
|
163
164
|
}
|
|
164
165
|
|
|
165
166
|
*getL2Levels(side: 'bids' | 'asks'): Generator<L2Level> {
|
|
166
|
-
const
|
|
167
|
-
|
|
168
|
-
|
|
167
|
+
const tickSize = this.market.data.header
|
|
168
|
+
.tickSizeInQuoteAtomsPerBaseUnit as BN;
|
|
169
|
+
const baseLotsToRawBaseUnits = this.market.baseLotsToRawBaseUnits(1);
|
|
170
|
+
|
|
171
|
+
const basePrecision = new BN(
|
|
172
|
+
Math.pow(10, this.market.data.header.baseParams.decimals) *
|
|
173
|
+
baseLotsToRawBaseUnits
|
|
169
174
|
);
|
|
170
|
-
const pricePrecision = PRICE_PRECISION.toNumber();
|
|
171
175
|
|
|
172
|
-
const
|
|
176
|
+
const pricePrecision = PRICE_PRECISION.div(tickSize as BN);
|
|
177
|
+
|
|
178
|
+
const ladder = getMarketLadder(
|
|
173
179
|
this.market,
|
|
174
180
|
this.lastSlot,
|
|
175
181
|
this.lastUnixTimestamp,
|
|
@@ -177,10 +183,10 @@ export class PhoenixSubscriber implements L2OrderBookGenerator {
|
|
|
177
183
|
);
|
|
178
184
|
|
|
179
185
|
for (let i = 0; i < ladder[side].length; i++) {
|
|
180
|
-
const {
|
|
181
|
-
const size =
|
|
186
|
+
const { priceInTicks, sizeInBaseLots } = ladder[side][i];
|
|
187
|
+
const size = sizeInBaseLots.mul(basePrecision);
|
|
182
188
|
yield {
|
|
183
|
-
price:
|
|
189
|
+
price: priceInTicks.mul(new BN(pricePrecision)),
|
|
184
190
|
size,
|
|
185
191
|
sources: {
|
|
186
192
|
phoenix: size,
|