@drift-labs/sdk 2.82.0-beta.0 → 2.82.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/README.md +65 -47
- package/VERSION +1 -1
- package/lib/accounts/types.d.ts +4 -0
- package/lib/accounts/webSocketAccountSubscriber.d.ts +3 -3
- package/lib/accounts/webSocketAccountSubscriber.js +15 -8
- package/lib/accounts/webSocketDriftClientAccountSubscriber.d.ts +3 -3
- package/lib/accounts/webSocketDriftClientAccountSubscriber.js +5 -5
- package/lib/accounts/webSocketInsuranceFundStakeAccountSubscriber.d.ts +2 -2
- package/lib/accounts/webSocketInsuranceFundStakeAccountSubscriber.js +5 -3
- package/lib/accounts/webSocketProgramAccountSubscriber.d.ts +3 -3
- package/lib/accounts/webSocketProgramAccountSubscriber.js +15 -9
- package/lib/accounts/webSocketUserAccountSubscriber.d.ts +3 -3
- package/lib/accounts/webSocketUserAccountSubscriber.js +3 -3
- package/lib/accounts/webSocketUserStatsAccountSubsriber.d.ts +3 -3
- package/lib/accounts/webSocketUserStatsAccountSubsriber.js +3 -3
- package/lib/auctionSubscriber/auctionSubscriber.d.ts +2 -2
- package/lib/auctionSubscriber/auctionSubscriber.js +3 -3
- package/lib/auctionSubscriber/types.d.ts +1 -0
- package/lib/constants/perpMarkets.js +2 -2
- package/lib/driftClient.d.ts +12 -1
- package/lib/driftClient.js +59 -16
- package/lib/driftClientConfig.d.ts +1 -0
- package/lib/orderSubscriber/OrderSubscriber.js +6 -3
- package/lib/orderSubscriber/WebsocketSubscription.d.ts +4 -3
- package/lib/orderSubscriber/WebsocketSubscription.js +3 -3
- package/lib/orderSubscriber/types.d.ts +1 -0
- package/lib/priorityFee/driftPriorityFeeMethod.d.ts +13 -3
- package/lib/priorityFee/driftPriorityFeeMethod.js +2 -2
- package/lib/priorityFee/index.d.ts +2 -0
- package/lib/priorityFee/index.js +2 -0
- package/lib/priorityFee/priorityFeeSubscriber.d.ts +1 -4
- package/lib/priorityFee/priorityFeeSubscriber.js +5 -4
- package/lib/priorityFee/priorityFeeSubscriberMap.d.ts +48 -0
- package/lib/priorityFee/priorityFeeSubscriberMap.js +88 -0
- package/lib/priorityFee/types.d.ts +8 -3
- package/lib/priorityFee/types.js +2 -1
- package/lib/tx/baseTxSender.js +3 -2
- package/lib/tx/fastSingleTxSender.d.ts +2 -0
- package/lib/tx/fastSingleTxSender.js +10 -8
- package/lib/tx/types.d.ts +5 -0
- package/lib/tx/types.js +12 -1
- package/lib/tx/utils.js +5 -1
- package/lib/user.d.ts +0 -10
- package/lib/user.js +6 -29
- package/lib/userConfig.d.ts +1 -0
- package/lib/userMap/WebsocketSubscription.d.ts +4 -3
- package/lib/userMap/WebsocketSubscription.js +3 -3
- package/lib/userMap/userMap.js +4 -1
- package/lib/userMap/userMapConfig.d.ts +1 -0
- package/lib/userStats.js +6 -3
- package/lib/userStatsConfig.d.ts +1 -0
- package/package.json +3 -3
- package/src/accounts/types.ts +5 -0
- package/src/accounts/webSocketAccountSubscriber.ts +34 -22
- package/src/accounts/webSocketDriftClientAccountSubscriber.ts +7 -6
- package/src/accounts/webSocketInsuranceFundStakeAccountSubscriber.ts +6 -4
- package/src/accounts/webSocketProgramAccountSubscriber.ts +32 -22
- package/src/accounts/webSocketUserAccountSubscriber.ts +5 -4
- package/src/accounts/webSocketUserStatsAccountSubsriber.ts +5 -4
- package/src/auctionSubscriber/auctionSubscriber.ts +10 -4
- package/src/auctionSubscriber/types.ts +1 -0
- package/src/blockhashSubscriber/types.ts +4 -0
- package/src/constants/perpMarkets.ts +2 -2
- package/src/driftClient.ts +70 -12
- package/src/driftClientConfig.ts +1 -0
- package/src/orderSubscriber/OrderSubscriber.ts +4 -1
- package/src/orderSubscriber/WebsocketSubscription.ts +6 -5
- package/src/orderSubscriber/types.ts +1 -0
- package/src/priorityFee/driftPriorityFeeMethod.ts +16 -4
- package/src/priorityFee/index.ts +2 -0
- package/src/priorityFee/priorityFeeSubscriber.ts +7 -7
- package/src/priorityFee/priorityFeeSubscriberMap.ts +112 -0
- package/src/priorityFee/types.ts +16 -3
- package/src/tx/baseTxSender.ts +8 -4
- package/src/tx/fastSingleTxSender.ts +12 -9
- package/src/tx/types.ts +12 -0
- package/src/tx/utils.ts +5 -1
- package/src/user.ts +7 -32
- package/src/userConfig.ts +1 -0
- package/src/userMap/WebsocketSubscription.ts +6 -5
- package/src/userMap/userMap.ts +4 -1
- package/src/userMap/userMapConfig.ts +1 -0
- package/src/userStats.ts +4 -1
- package/src/userStatsConfig.ts +1 -0
- package/tests/dlob/helpers.ts +4 -0
package/README.md
CHANGED
|
@@ -19,6 +19,13 @@ npm i @drift-labs/sdk
|
|
|
19
19
|
|
|
20
20
|
## Getting Started
|
|
21
21
|
|
|
22
|
+
Documentation:
|
|
23
|
+
|
|
24
|
+
- [API docs](https://drift-labs.github.io/v2-teacher/)
|
|
25
|
+
- [overview docs](https://docs.drift.trade/)
|
|
26
|
+
|
|
27
|
+
The below is a light overview of using solana and drift's typescript sdk, but not as comprehensive as the [API docs](https://drift-labs.github.io/v2-teacher/)
|
|
28
|
+
|
|
22
29
|
### Setting up a wallet for your program
|
|
23
30
|
|
|
24
31
|
```bash
|
|
@@ -77,8 +84,10 @@ convertToNumber(new BN(10500), new BN(1000)); // = 10.5
|
|
|
77
84
|
### Setting up an account and making a trade
|
|
78
85
|
|
|
79
86
|
```typescript
|
|
80
|
-
import
|
|
81
|
-
import {
|
|
87
|
+
import * as anchor from '@coral-xyz/anchor';
|
|
88
|
+
import { AnchorProvider } from '@coral-xyz/anchor';
|
|
89
|
+
import { getAssociatedTokenAddress, TOKEN_PROGRAM_ID } from '@solana/spl-token';
|
|
90
|
+
|
|
82
91
|
import { Connection, Keypair, PublicKey } from '@solana/web3.js';
|
|
83
92
|
import {
|
|
84
93
|
calculateReservePrice,
|
|
@@ -95,16 +104,17 @@ import {
|
|
|
95
104
|
BASE_PRECISION,
|
|
96
105
|
getMarketOrderParams,
|
|
97
106
|
BulkAccountLoader,
|
|
98
|
-
|
|
107
|
+
BN,
|
|
108
|
+
calculateBidAskPrice,
|
|
109
|
+
getMarketsAndOraclesForSubscription,
|
|
110
|
+
calculateEstimatedPerpEntryPrice,
|
|
99
111
|
} from '../sdk';
|
|
100
112
|
|
|
101
113
|
export const getTokenAddress = (
|
|
102
114
|
mintAddress: string,
|
|
103
115
|
userPubKey: string
|
|
104
116
|
): Promise<PublicKey> => {
|
|
105
|
-
return
|
|
106
|
-
new PublicKey(`ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL`),
|
|
107
|
-
TOKEN_PROGRAM_ID,
|
|
117
|
+
return getAssociatedTokenAddress(
|
|
108
118
|
new PublicKey(mintAddress),
|
|
109
119
|
new PublicKey(userPubKey)
|
|
110
120
|
);
|
|
@@ -112,49 +122,56 @@ export const getTokenAddress = (
|
|
|
112
122
|
|
|
113
123
|
const main = async () => {
|
|
114
124
|
const env = 'devnet';
|
|
125
|
+
// const env = 'mainnet-beta';
|
|
126
|
+
|
|
115
127
|
// Initialize Drift SDK
|
|
116
128
|
const sdkConfig = initialize({ env });
|
|
117
129
|
|
|
118
130
|
// Set up the Wallet and Provider
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
);
|
|
123
|
-
const wallet = new Wallet(keypair);
|
|
131
|
+
if (!process.env.ANCHOR_WALLET) {
|
|
132
|
+
throw new Error('ANCHOR_WALLET env var must be set.');
|
|
133
|
+
}
|
|
124
134
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
135
|
+
if (!process.env.ANCHOR_PROVIDER_URL) {
|
|
136
|
+
throw new Error('ANCHOR_PROVIDER_URL env var must be set.');
|
|
137
|
+
}
|
|
128
138
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
139
|
+
const provider = anchor.AnchorProvider.local(
|
|
140
|
+
process.env.ANCHOR_PROVIDER_URL,
|
|
141
|
+
{
|
|
142
|
+
preflightCommitment: 'confirmed',
|
|
143
|
+
skipPreflight: false,
|
|
144
|
+
commitment: 'confirmed',
|
|
145
|
+
}
|
|
134
146
|
);
|
|
135
|
-
|
|
136
147
|
// Check SOL Balance
|
|
137
|
-
const lamportsBalance = await connection.getBalance(
|
|
138
|
-
|
|
148
|
+
const lamportsBalance = await provider.connection.getBalance(
|
|
149
|
+
provider.wallet.publicKey
|
|
150
|
+
);
|
|
151
|
+
console.log(
|
|
152
|
+
provider.wallet.publicKey.toString(),
|
|
153
|
+
env,
|
|
154
|
+
'SOL balance:',
|
|
155
|
+
lamportsBalance / 10 ** 9
|
|
156
|
+
);
|
|
139
157
|
|
|
140
158
|
// Misc. other things to set up
|
|
141
159
|
const usdcTokenAddress = await getTokenAddress(
|
|
142
160
|
sdkConfig.USDC_MINT_ADDRESS,
|
|
143
|
-
wallet.publicKey.toString()
|
|
161
|
+
provider.wallet.publicKey.toString()
|
|
144
162
|
);
|
|
145
163
|
|
|
146
164
|
// Set up the Drift Client
|
|
147
165
|
const driftPublicKey = new PublicKey(sdkConfig.DRIFT_PROGRAM_ID);
|
|
148
166
|
const bulkAccountLoader = new BulkAccountLoader(
|
|
149
|
-
connection,
|
|
167
|
+
provider.connection,
|
|
150
168
|
'confirmed',
|
|
151
169
|
1000
|
|
152
170
|
);
|
|
153
171
|
const driftClient = new DriftClient({
|
|
154
|
-
connection,
|
|
172
|
+
connection: provider.connection,
|
|
155
173
|
wallet: provider.wallet,
|
|
156
174
|
programID: driftPublicKey,
|
|
157
|
-
...getMarketsAndOraclesForSubscription(env),
|
|
158
175
|
accountSubscription: {
|
|
159
176
|
type: 'polling',
|
|
160
177
|
accountLoader: bulkAccountLoader,
|
|
@@ -162,6 +179,8 @@ const main = async () => {
|
|
|
162
179
|
});
|
|
163
180
|
await driftClient.subscribe();
|
|
164
181
|
|
|
182
|
+
console.log('subscribed to driftClient');
|
|
183
|
+
|
|
165
184
|
// Set up user client
|
|
166
185
|
const user = new User({
|
|
167
186
|
driftClient: driftClient,
|
|
@@ -176,13 +195,20 @@ const main = async () => {
|
|
|
176
195
|
const userAccountExists = await user.exists();
|
|
177
196
|
|
|
178
197
|
if (!userAccountExists) {
|
|
179
|
-
|
|
198
|
+
console.log(
|
|
199
|
+
'initializing to',
|
|
200
|
+
env,
|
|
201
|
+
' drift account for',
|
|
202
|
+
provider.wallet.publicKey.toString()
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
//// Create a Drift V2 account by Depositing some USDC ($10,000 in this case)
|
|
180
206
|
const depositAmount = new BN(10000).mul(QUOTE_PRECISION);
|
|
181
207
|
await driftClient.initializeUserAccountAndDepositCollateral(
|
|
182
208
|
depositAmount,
|
|
183
209
|
await getTokenAddress(
|
|
184
210
|
usdcTokenAddress.toString(),
|
|
185
|
-
wallet.publicKey.toString()
|
|
211
|
+
provider.wallet.publicKey.toString()
|
|
186
212
|
)
|
|
187
213
|
);
|
|
188
214
|
}
|
|
@@ -194,6 +220,9 @@ const main = async () => {
|
|
|
194
220
|
(market) => market.baseAssetSymbol === 'SOL'
|
|
195
221
|
);
|
|
196
222
|
|
|
223
|
+
const marketIndex = solMarketInfo.marketIndex;
|
|
224
|
+
|
|
225
|
+
// Get vAMM bid and ask price
|
|
197
226
|
const [bid, ask] = calculateBidAskPrice(
|
|
198
227
|
driftClient.getPerpMarketAccount(marketIndex).amm,
|
|
199
228
|
driftClient.getOracleDataForPerpMarket(marketIndex)
|
|
@@ -203,35 +232,26 @@ const main = async () => {
|
|
|
203
232
|
const formattedAskPrice = convertToNumber(ask, PRICE_PRECISION);
|
|
204
233
|
|
|
205
234
|
console.log(
|
|
206
|
-
|
|
235
|
+
env,
|
|
236
|
+
`vAMM bid: $${formattedBidPrice} and ask: $${formattedAskPrice}`
|
|
207
237
|
);
|
|
208
238
|
|
|
209
|
-
// Estimate the slippage for a $5000 LONG trade
|
|
210
239
|
const solMarketAccount = driftClient.getPerpMarketAccount(
|
|
211
240
|
solMarketInfo.marketIndex
|
|
212
241
|
);
|
|
242
|
+
console.log(env, `Placing a 1 SOL-PERP LONG order`);
|
|
213
243
|
|
|
214
|
-
const
|
|
215
|
-
calculateTradeSlippage(
|
|
216
|
-
PositionDirection.LONG,
|
|
217
|
-
new BN(1).mul(BASE_PRECISION),
|
|
218
|
-
solMarketAccount,
|
|
219
|
-
'base',
|
|
220
|
-
driftClient.getOracleDataForPerpMarket(solMarketInfo.marketIndex)
|
|
221
|
-
)[0],
|
|
222
|
-
PRICE_PRECISION
|
|
223
|
-
);
|
|
224
|
-
|
|
225
|
-
console.log(`Slippage for a 1 SOL-PERP would be $${slippage}`);
|
|
226
|
-
|
|
227
|
-
await driftClient.placePerpOrder(
|
|
244
|
+
const txSig = await driftClient.placePerpOrder(
|
|
228
245
|
getMarketOrderParams({
|
|
229
246
|
baseAssetAmount: new BN(1).mul(BASE_PRECISION),
|
|
230
247
|
direction: PositionDirection.LONG,
|
|
231
248
|
marketIndex: solMarketAccount.marketIndex,
|
|
232
249
|
})
|
|
233
250
|
);
|
|
234
|
-
console.log(
|
|
251
|
+
console.log(
|
|
252
|
+
env,
|
|
253
|
+
`Placed a 1 SOL-PERP LONG order. Tranaction signature: ${txSig}`
|
|
254
|
+
);
|
|
235
255
|
};
|
|
236
256
|
|
|
237
257
|
main();
|
|
@@ -244,5 +264,3 @@ Drift Protocol v2 is licensed under [Apache 2.0](./LICENSE).
|
|
|
244
264
|
Unless you explicitly state otherwise, any contribution intentionally submitted
|
|
245
265
|
for inclusion in Drift SDK by you, as defined in the Apache-2.0 license, shall be
|
|
246
266
|
licensed as above, without any additional terms or conditions.
|
|
247
|
-
|
|
248
|
-
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.82.0-beta.
|
|
1
|
+
2.82.0-beta.10
|
package/lib/accounts/types.d.ts
CHANGED
|
@@ -126,6 +126,10 @@ export type DataAndSlot<T> = {
|
|
|
126
126
|
data: T;
|
|
127
127
|
slot: number;
|
|
128
128
|
};
|
|
129
|
+
export type ResubOpts = {
|
|
130
|
+
resubTimeoutMs?: number;
|
|
131
|
+
logResubMessages?: boolean;
|
|
132
|
+
};
|
|
129
133
|
export interface UserStatsAccountEvents {
|
|
130
134
|
userStatsAccountUpdate: (payload: UserStatsAccount) => void;
|
|
131
135
|
update: void;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
/// <reference types="node" />
|
|
3
|
-
import { DataAndSlot, BufferAndSlot, AccountSubscriber } from './types';
|
|
3
|
+
import { DataAndSlot, BufferAndSlot, AccountSubscriber, ResubOpts } from './types';
|
|
4
4
|
import { Program } from '@coral-xyz/anchor';
|
|
5
5
|
import { AccountInfo, Commitment, Context, PublicKey } from '@solana/web3.js';
|
|
6
6
|
export declare class WebSocketAccountSubscriber<T> implements AccountSubscriber<T> {
|
|
@@ -12,12 +12,12 @@ export declare class WebSocketAccountSubscriber<T> implements AccountSubscriber<
|
|
|
12
12
|
decodeBufferFn: (buffer: Buffer) => T;
|
|
13
13
|
onChange: (data: T) => void;
|
|
14
14
|
listenerId?: number;
|
|
15
|
-
|
|
15
|
+
resubOpts?: ResubOpts;
|
|
16
16
|
commitment?: Commitment;
|
|
17
17
|
isUnsubscribing: boolean;
|
|
18
18
|
timeoutId?: NodeJS.Timeout;
|
|
19
19
|
receivingData: boolean;
|
|
20
|
-
constructor(accountName: string, program: Program, accountPublicKey: PublicKey, decodeBuffer?: (buffer: Buffer) => T,
|
|
20
|
+
constructor(accountName: string, program: Program, accountPublicKey: PublicKey, decodeBuffer?: (buffer: Buffer) => T, resubOpts?: ResubOpts, commitment?: Commitment);
|
|
21
21
|
subscribe(onChange: (data: T) => void): Promise<void>;
|
|
22
22
|
setData(data: T, slot?: number): void;
|
|
23
23
|
private setTimeout;
|
|
@@ -3,14 +3,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.WebSocketAccountSubscriber = void 0;
|
|
4
4
|
const utils_1 = require("./utils");
|
|
5
5
|
class WebSocketAccountSubscriber {
|
|
6
|
-
constructor(accountName, program, accountPublicKey, decodeBuffer,
|
|
6
|
+
constructor(accountName, program, accountPublicKey, decodeBuffer, resubOpts, commitment) {
|
|
7
|
+
var _a;
|
|
7
8
|
this.isUnsubscribing = false;
|
|
8
9
|
this.accountName = accountName;
|
|
9
10
|
this.program = program;
|
|
10
11
|
this.accountPublicKey = accountPublicKey;
|
|
11
12
|
this.decodeBufferFn = decodeBuffer;
|
|
12
|
-
this.
|
|
13
|
-
if (this.resubTimeoutMs < 1000) {
|
|
13
|
+
this.resubOpts = resubOpts;
|
|
14
|
+
if (((_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.resubTimeoutMs) < 1000) {
|
|
14
15
|
console.log('resubTimeoutMs should be at least 1000ms to avoid spamming resub');
|
|
15
16
|
}
|
|
16
17
|
this.receivingData = false;
|
|
@@ -18,6 +19,7 @@ class WebSocketAccountSubscriber {
|
|
|
18
19
|
commitment !== null && commitment !== void 0 ? commitment : this.program.provider.opts.commitment;
|
|
19
20
|
}
|
|
20
21
|
async subscribe(onChange) {
|
|
22
|
+
var _a;
|
|
21
23
|
if (this.listenerId != null || this.isUnsubscribing) {
|
|
22
24
|
return;
|
|
23
25
|
}
|
|
@@ -26,7 +28,8 @@ class WebSocketAccountSubscriber {
|
|
|
26
28
|
await this.fetch();
|
|
27
29
|
}
|
|
28
30
|
this.listenerId = this.program.provider.connection.onAccountChange(this.accountPublicKey, (accountInfo, context) => {
|
|
29
|
-
|
|
31
|
+
var _a;
|
|
32
|
+
if ((_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.resubTimeoutMs) {
|
|
30
33
|
this.receivingData = true;
|
|
31
34
|
clearTimeout(this.timeoutId);
|
|
32
35
|
this.handleRpcResponse(context, accountInfo);
|
|
@@ -36,7 +39,7 @@ class WebSocketAccountSubscriber {
|
|
|
36
39
|
this.handleRpcResponse(context, accountInfo);
|
|
37
40
|
}
|
|
38
41
|
}, this.commitment);
|
|
39
|
-
if (this.resubTimeoutMs) {
|
|
42
|
+
if ((_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.resubTimeoutMs) {
|
|
40
43
|
this.receivingData = true;
|
|
41
44
|
this.setTimeout();
|
|
42
45
|
}
|
|
@@ -52,21 +55,25 @@ class WebSocketAccountSubscriber {
|
|
|
52
55
|
};
|
|
53
56
|
}
|
|
54
57
|
setTimeout() {
|
|
58
|
+
var _a;
|
|
55
59
|
if (!this.onChange) {
|
|
56
60
|
throw new Error('onChange callback function must be set');
|
|
57
61
|
}
|
|
58
62
|
this.timeoutId = setTimeout(async () => {
|
|
63
|
+
var _a;
|
|
59
64
|
if (this.isUnsubscribing) {
|
|
60
65
|
// If we are in the process of unsubscribing, do not attempt to resubscribe
|
|
61
66
|
return;
|
|
62
67
|
}
|
|
63
68
|
if (this.receivingData) {
|
|
64
|
-
|
|
69
|
+
if ((_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.logResubMessages) {
|
|
70
|
+
console.log(`No ws data from ${this.accountName} in ${this.resubOpts.resubTimeoutMs}ms, resubscribing`);
|
|
71
|
+
}
|
|
65
72
|
await this.unsubscribe(true);
|
|
66
73
|
this.receivingData = false;
|
|
67
74
|
await this.subscribe(this.onChange);
|
|
68
75
|
}
|
|
69
|
-
}, this.resubTimeoutMs);
|
|
76
|
+
}, (_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.resubTimeoutMs);
|
|
70
77
|
}
|
|
71
78
|
async fetch() {
|
|
72
79
|
const rpcResponse = await this.program.provider.connection.getAccountInfoAndContext(this.accountPublicKey, this.program.provider.opts.commitment);
|
|
@@ -120,7 +127,7 @@ class WebSocketAccountSubscriber {
|
|
|
120
127
|
}
|
|
121
128
|
unsubscribe(onResub = false) {
|
|
122
129
|
if (!onResub) {
|
|
123
|
-
this.resubTimeoutMs = undefined;
|
|
130
|
+
this.resubOpts.resubTimeoutMs = undefined;
|
|
124
131
|
}
|
|
125
132
|
this.isUnsubscribing = true;
|
|
126
133
|
clearTimeout(this.timeoutId);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import { DriftClientAccountSubscriber, DriftClientAccountEvents, DataAndSlot } from './types';
|
|
2
|
+
import { DriftClientAccountSubscriber, DriftClientAccountEvents, DataAndSlot, ResubOpts } from './types';
|
|
3
3
|
import { AccountSubscriber } from './types';
|
|
4
4
|
import { SpotMarketAccount, PerpMarketAccount, StateAccount } from '../types';
|
|
5
5
|
import { Program } from '@coral-xyz/anchor';
|
|
@@ -16,7 +16,7 @@ export declare class WebSocketDriftClientAccountSubscriber implements DriftClien
|
|
|
16
16
|
spotMarketIndexes: number[];
|
|
17
17
|
oracleInfos: OracleInfo[];
|
|
18
18
|
oracleClientCache: OracleClientCache;
|
|
19
|
-
|
|
19
|
+
resubOpts?: ResubOpts;
|
|
20
20
|
shouldFindAllMarketsAndOracles: boolean;
|
|
21
21
|
eventEmitter: StrictEventEmitter<EventEmitter, DriftClientAccountEvents>;
|
|
22
22
|
stateAccountSubscriber?: AccountSubscriber<StateAccount>;
|
|
@@ -28,7 +28,7 @@ export declare class WebSocketDriftClientAccountSubscriber implements DriftClien
|
|
|
28
28
|
private isSubscribing;
|
|
29
29
|
private subscriptionPromise;
|
|
30
30
|
private subscriptionPromiseResolver;
|
|
31
|
-
constructor(program: Program, perpMarketIndexes: number[], spotMarketIndexes: number[], oracleInfos: OracleInfo[], shouldFindAllMarketsAndOracles: boolean,
|
|
31
|
+
constructor(program: Program, perpMarketIndexes: number[], spotMarketIndexes: number[], oracleInfos: OracleInfo[], shouldFindAllMarketsAndOracles: boolean, resubOpts?: ResubOpts, commitment?: Commitment);
|
|
32
32
|
subscribe(): Promise<boolean>;
|
|
33
33
|
subscribeToPerpMarketAccounts(): Promise<boolean>;
|
|
34
34
|
subscribeToPerpMarketAccount(marketIndex: number): Promise<boolean>;
|
|
@@ -10,7 +10,7 @@ const oracleClientCache_1 = require("../oracles/oracleClientCache");
|
|
|
10
10
|
const quoteAssetOracleClient_1 = require("../oracles/quoteAssetOracleClient");
|
|
11
11
|
const config_1 = require("../config");
|
|
12
12
|
class WebSocketDriftClientAccountSubscriber {
|
|
13
|
-
constructor(program, perpMarketIndexes, spotMarketIndexes, oracleInfos, shouldFindAllMarketsAndOracles,
|
|
13
|
+
constructor(program, perpMarketIndexes, spotMarketIndexes, oracleInfos, shouldFindAllMarketsAndOracles, resubOpts, commitment) {
|
|
14
14
|
this.oracleClientCache = new oracleClientCache_1.OracleClientCache();
|
|
15
15
|
this.perpMarketAccountSubscribers = new Map();
|
|
16
16
|
this.perpOracleMap = new Map();
|
|
@@ -25,7 +25,7 @@ class WebSocketDriftClientAccountSubscriber {
|
|
|
25
25
|
this.spotMarketIndexes = spotMarketIndexes;
|
|
26
26
|
this.oracleInfos = oracleInfos;
|
|
27
27
|
this.shouldFindAllMarketsAndOracles = shouldFindAllMarketsAndOracles;
|
|
28
|
-
this.
|
|
28
|
+
this.resubOpts = resubOpts;
|
|
29
29
|
this.commitment = commitment;
|
|
30
30
|
}
|
|
31
31
|
async subscribe() {
|
|
@@ -74,7 +74,7 @@ class WebSocketDriftClientAccountSubscriber {
|
|
|
74
74
|
}
|
|
75
75
|
async subscribeToPerpMarketAccount(marketIndex) {
|
|
76
76
|
const perpMarketPublicKey = await (0, pda_1.getPerpMarketPublicKey)(this.program.programId, marketIndex);
|
|
77
|
-
const accountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('perpMarket', this.program, perpMarketPublicKey, undefined, this.
|
|
77
|
+
const accountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('perpMarket', this.program, perpMarketPublicKey, undefined, this.resubOpts, this.commitment);
|
|
78
78
|
await accountSubscriber.subscribe((data) => {
|
|
79
79
|
this.eventEmitter.emit('perpMarketAccountUpdate', data);
|
|
80
80
|
this.eventEmitter.emit('update');
|
|
@@ -90,7 +90,7 @@ class WebSocketDriftClientAccountSubscriber {
|
|
|
90
90
|
}
|
|
91
91
|
async subscribeToSpotMarketAccount(marketIndex) {
|
|
92
92
|
const marketPublicKey = await (0, pda_1.getSpotMarketPublicKey)(this.program.programId, marketIndex);
|
|
93
|
-
const accountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('spotMarket', this.program, marketPublicKey, undefined, this.
|
|
93
|
+
const accountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('spotMarket', this.program, marketPublicKey, undefined, this.resubOpts, this.commitment);
|
|
94
94
|
await accountSubscriber.subscribe((data) => {
|
|
95
95
|
this.eventEmitter.emit('spotMarketAccountUpdate', data);
|
|
96
96
|
this.eventEmitter.emit('update');
|
|
@@ -110,7 +110,7 @@ class WebSocketDriftClientAccountSubscriber {
|
|
|
110
110
|
const client = this.oracleClientCache.get(oracleInfo.source, this.program.provider.connection, this.program);
|
|
111
111
|
const accountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('oracle', this.program, oracleInfo.publicKey, (buffer) => {
|
|
112
112
|
return client.getOraclePriceDataFromBuffer(buffer);
|
|
113
|
-
}, this.
|
|
113
|
+
}, this.resubOpts, this.commitment);
|
|
114
114
|
await accountSubscriber.subscribe((data) => {
|
|
115
115
|
this.eventEmitter.emit('oraclePriceUpdate', oracleInfo.publicKey, data);
|
|
116
116
|
this.eventEmitter.emit('update');
|
|
@@ -7,13 +7,13 @@ import { Commitment, PublicKey } from '@solana/web3.js';
|
|
|
7
7
|
import { InsuranceFundStake } from '../types';
|
|
8
8
|
export declare class WebSocketInsuranceFundStakeAccountSubscriber implements InsuranceFundStakeAccountSubscriber {
|
|
9
9
|
isSubscribed: boolean;
|
|
10
|
-
|
|
10
|
+
resubTimeoutMs?: number;
|
|
11
11
|
commitment?: Commitment;
|
|
12
12
|
program: Program;
|
|
13
13
|
eventEmitter: StrictEventEmitter<EventEmitter, InsuranceFundStakeAccountEvents>;
|
|
14
14
|
insuranceFundStakeAccountPublicKey: PublicKey;
|
|
15
15
|
insuranceFundStakeDataAccountSubscriber: AccountSubscriber<InsuranceFundStake>;
|
|
16
|
-
constructor(program: Program, insuranceFundStakeAccountPublicKey: PublicKey,
|
|
16
|
+
constructor(program: Program, insuranceFundStakeAccountPublicKey: PublicKey, resubTimeoutMs?: number, commitment?: Commitment);
|
|
17
17
|
subscribe(insuranceFundStakeAccount?: InsuranceFundStake): Promise<boolean>;
|
|
18
18
|
fetch(): Promise<void>;
|
|
19
19
|
unsubscribe(): Promise<void>;
|
|
@@ -5,13 +5,13 @@ const types_1 = require("./types");
|
|
|
5
5
|
const events_1 = require("events");
|
|
6
6
|
const webSocketAccountSubscriber_1 = require("./webSocketAccountSubscriber");
|
|
7
7
|
class WebSocketInsuranceFundStakeAccountSubscriber {
|
|
8
|
-
constructor(program, insuranceFundStakeAccountPublicKey,
|
|
8
|
+
constructor(program, insuranceFundStakeAccountPublicKey, resubTimeoutMs, commitment) {
|
|
9
9
|
this.isSubscribed = false;
|
|
10
10
|
this.program = program;
|
|
11
11
|
this.insuranceFundStakeAccountPublicKey =
|
|
12
12
|
insuranceFundStakeAccountPublicKey;
|
|
13
13
|
this.eventEmitter = new events_1.EventEmitter();
|
|
14
|
-
this.
|
|
14
|
+
this.resubTimeoutMs = resubTimeoutMs;
|
|
15
15
|
this.commitment = commitment;
|
|
16
16
|
}
|
|
17
17
|
async subscribe(insuranceFundStakeAccount) {
|
|
@@ -19,7 +19,9 @@ class WebSocketInsuranceFundStakeAccountSubscriber {
|
|
|
19
19
|
return true;
|
|
20
20
|
}
|
|
21
21
|
this.insuranceFundStakeDataAccountSubscriber =
|
|
22
|
-
new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('insuranceFundStake', this.program, this.insuranceFundStakeAccountPublicKey, undefined,
|
|
22
|
+
new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('insuranceFundStake', this.program, this.insuranceFundStakeAccountPublicKey, undefined, {
|
|
23
|
+
resubTimeoutMs: this.resubTimeoutMs,
|
|
24
|
+
}, this.commitment);
|
|
23
25
|
if (insuranceFundStakeAccount) {
|
|
24
26
|
this.insuranceFundStakeDataAccountSubscriber.setData(insuranceFundStakeAccount);
|
|
25
27
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
/// <reference types="node" />
|
|
3
|
-
import { DataAndSlot, BufferAndSlot, ProgramAccountSubscriber } from './types';
|
|
3
|
+
import { DataAndSlot, BufferAndSlot, ProgramAccountSubscriber, ResubOpts } from './types';
|
|
4
4
|
import { Program } from '@coral-xyz/anchor';
|
|
5
5
|
import { Commitment, Context, KeyedAccountInfo, MemcmpFilter, PublicKey } from '@solana/web3.js';
|
|
6
6
|
export declare class WebSocketProgramAccountSubscriber<T> implements ProgramAccountSubscriber<T> {
|
|
@@ -14,7 +14,7 @@ export declare class WebSocketProgramAccountSubscriber<T> implements ProgramAcco
|
|
|
14
14
|
decodeBuffer: (accountName: string, ix: Buffer) => T;
|
|
15
15
|
onChange: (accountId: PublicKey, data: T, context: Context, buffer: Buffer) => void;
|
|
16
16
|
listenerId?: number;
|
|
17
|
-
|
|
17
|
+
resubOpts?: ResubOpts;
|
|
18
18
|
isUnsubscribing: boolean;
|
|
19
19
|
timeoutId?: NodeJS.Timeout;
|
|
20
20
|
options: {
|
|
@@ -25,7 +25,7 @@ export declare class WebSocketProgramAccountSubscriber<T> implements ProgramAcco
|
|
|
25
25
|
constructor(subscriptionName: string, accountDiscriminator: string, program: Program, decodeBufferFn: (accountName: string, ix: Buffer) => T, options?: {
|
|
26
26
|
filters: MemcmpFilter[];
|
|
27
27
|
commitment?: Commitment;
|
|
28
|
-
},
|
|
28
|
+
}, resubOpts?: ResubOpts);
|
|
29
29
|
subscribe(onChange: (accountId: PublicKey, data: T, context: Context, buffer: Buffer) => void): Promise<void>;
|
|
30
30
|
private setTimeout;
|
|
31
31
|
handleRpcResponse(context: Context, keyedAccountInfo: KeyedAccountInfo): void;
|
|
@@ -4,28 +4,30 @@ exports.WebSocketProgramAccountSubscriber = void 0;
|
|
|
4
4
|
class WebSocketProgramAccountSubscriber {
|
|
5
5
|
constructor(subscriptionName, accountDiscriminator, program, decodeBufferFn, options = {
|
|
6
6
|
filters: [],
|
|
7
|
-
},
|
|
7
|
+
}, resubOpts) {
|
|
8
|
+
var _a;
|
|
8
9
|
this.isUnsubscribing = false;
|
|
9
10
|
this.receivingData = false;
|
|
10
11
|
this.subscriptionName = subscriptionName;
|
|
11
12
|
this.accountDiscriminator = accountDiscriminator;
|
|
12
13
|
this.program = program;
|
|
13
14
|
this.decodeBuffer = decodeBufferFn;
|
|
14
|
-
this.
|
|
15
|
-
if (this.resubTimeoutMs < 1000) {
|
|
15
|
+
this.resubOpts = resubOpts;
|
|
16
|
+
if (((_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.resubTimeoutMs) < 1000) {
|
|
16
17
|
console.log('resubTimeoutMs should be at least 1000ms to avoid spamming resub');
|
|
17
18
|
}
|
|
18
19
|
this.options = options;
|
|
19
20
|
this.receivingData = false;
|
|
20
21
|
}
|
|
21
22
|
async subscribe(onChange) {
|
|
22
|
-
var _a;
|
|
23
|
+
var _a, _b;
|
|
23
24
|
if (this.listenerId != null || this.isUnsubscribing) {
|
|
24
25
|
return;
|
|
25
26
|
}
|
|
26
27
|
this.onChange = onChange;
|
|
27
28
|
this.listenerId = this.program.provider.connection.onProgramAccountChange(this.program.programId, (keyedAccountInfo, context) => {
|
|
28
|
-
|
|
29
|
+
var _a;
|
|
30
|
+
if ((_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.resubTimeoutMs) {
|
|
29
31
|
this.receivingData = true;
|
|
30
32
|
clearTimeout(this.timeoutId);
|
|
31
33
|
this.handleRpcResponse(context, keyedAccountInfo);
|
|
@@ -35,27 +37,31 @@ class WebSocketProgramAccountSubscriber {
|
|
|
35
37
|
this.handleRpcResponse(context, keyedAccountInfo);
|
|
36
38
|
}
|
|
37
39
|
}, (_a = this.options.commitment) !== null && _a !== void 0 ? _a : this.program.provider.opts.commitment, this.options.filters);
|
|
38
|
-
if (this.resubTimeoutMs) {
|
|
40
|
+
if ((_b = this.resubOpts) === null || _b === void 0 ? void 0 : _b.resubTimeoutMs) {
|
|
39
41
|
this.receivingData = true;
|
|
40
42
|
this.setTimeout();
|
|
41
43
|
}
|
|
42
44
|
}
|
|
43
45
|
setTimeout() {
|
|
46
|
+
var _a;
|
|
44
47
|
if (!this.onChange) {
|
|
45
48
|
throw new Error('onChange callback function must be set');
|
|
46
49
|
}
|
|
47
50
|
this.timeoutId = setTimeout(async () => {
|
|
51
|
+
var _a, _b;
|
|
48
52
|
if (this.isUnsubscribing) {
|
|
49
53
|
// If we are in the process of unsubscribing, do not attempt to resubscribe
|
|
50
54
|
return;
|
|
51
55
|
}
|
|
52
56
|
if (this.receivingData) {
|
|
53
|
-
|
|
57
|
+
if ((_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.logResubMessages) {
|
|
58
|
+
console.log(`No ws data from ${this.subscriptionName} in ${(_b = this.resubOpts) === null || _b === void 0 ? void 0 : _b.resubTimeoutMs}ms, resubscribing`);
|
|
59
|
+
}
|
|
54
60
|
await this.unsubscribe(true);
|
|
55
61
|
this.receivingData = false;
|
|
56
62
|
await this.subscribe(this.onChange);
|
|
57
63
|
}
|
|
58
|
-
}, this.resubTimeoutMs);
|
|
64
|
+
}, (_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.resubTimeoutMs);
|
|
59
65
|
}
|
|
60
66
|
handleRpcResponse(context, keyedAccountInfo) {
|
|
61
67
|
const newSlot = context.slot;
|
|
@@ -99,7 +105,7 @@ class WebSocketProgramAccountSubscriber {
|
|
|
99
105
|
}
|
|
100
106
|
unsubscribe(onResub = false) {
|
|
101
107
|
if (!onResub) {
|
|
102
|
-
this.resubTimeoutMs = undefined;
|
|
108
|
+
this.resubOpts.resubTimeoutMs = undefined;
|
|
103
109
|
}
|
|
104
110
|
this.isUnsubscribing = true;
|
|
105
111
|
clearTimeout(this.timeoutId);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import { DataAndSlot, AccountSubscriber, UserAccountEvents, UserAccountSubscriber } from './types';
|
|
2
|
+
import { DataAndSlot, AccountSubscriber, UserAccountEvents, UserAccountSubscriber, ResubOpts } from './types';
|
|
3
3
|
import { Program } from '@coral-xyz/anchor';
|
|
4
4
|
import StrictEventEmitter from 'strict-event-emitter-types';
|
|
5
5
|
import { EventEmitter } from 'events';
|
|
@@ -7,13 +7,13 @@ import { Commitment, PublicKey } from '@solana/web3.js';
|
|
|
7
7
|
import { UserAccount } from '../types';
|
|
8
8
|
export declare class WebSocketUserAccountSubscriber implements UserAccountSubscriber {
|
|
9
9
|
isSubscribed: boolean;
|
|
10
|
-
|
|
10
|
+
resubOpts?: ResubOpts;
|
|
11
11
|
commitment?: Commitment;
|
|
12
12
|
program: Program;
|
|
13
13
|
eventEmitter: StrictEventEmitter<EventEmitter, UserAccountEvents>;
|
|
14
14
|
userAccountPublicKey: PublicKey;
|
|
15
15
|
userDataAccountSubscriber: AccountSubscriber<UserAccount>;
|
|
16
|
-
constructor(program: Program, userAccountPublicKey: PublicKey,
|
|
16
|
+
constructor(program: Program, userAccountPublicKey: PublicKey, resubOpts?: ResubOpts, commitment?: Commitment);
|
|
17
17
|
subscribe(userAccount?: UserAccount): Promise<boolean>;
|
|
18
18
|
fetch(): Promise<void>;
|
|
19
19
|
unsubscribe(): Promise<void>;
|
|
@@ -5,19 +5,19 @@ const types_1 = require("./types");
|
|
|
5
5
|
const events_1 = require("events");
|
|
6
6
|
const webSocketAccountSubscriber_1 = require("./webSocketAccountSubscriber");
|
|
7
7
|
class WebSocketUserAccountSubscriber {
|
|
8
|
-
constructor(program, userAccountPublicKey,
|
|
8
|
+
constructor(program, userAccountPublicKey, resubOpts, commitment) {
|
|
9
9
|
this.isSubscribed = false;
|
|
10
10
|
this.program = program;
|
|
11
|
+
this.resubOpts = resubOpts;
|
|
11
12
|
this.userAccountPublicKey = userAccountPublicKey;
|
|
12
13
|
this.eventEmitter = new events_1.EventEmitter();
|
|
13
|
-
this.reconnectTimeoutMs = reconnectTimeoutMs;
|
|
14
14
|
this.commitment = commitment;
|
|
15
15
|
}
|
|
16
16
|
async subscribe(userAccount) {
|
|
17
17
|
if (this.isSubscribed) {
|
|
18
18
|
return true;
|
|
19
19
|
}
|
|
20
|
-
this.userDataAccountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('user', this.program, this.userAccountPublicKey, undefined, this.
|
|
20
|
+
this.userDataAccountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('user', this.program, this.userAccountPublicKey, undefined, this.resubOpts, this.commitment);
|
|
21
21
|
if (userAccount) {
|
|
22
22
|
this.userDataAccountSubscriber.setData(userAccount);
|
|
23
23
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import { DataAndSlot, AccountSubscriber, UserStatsAccountSubscriber, UserStatsAccountEvents } from './types';
|
|
2
|
+
import { DataAndSlot, AccountSubscriber, UserStatsAccountSubscriber, UserStatsAccountEvents, ResubOpts } from './types';
|
|
3
3
|
import { Program } from '@coral-xyz/anchor';
|
|
4
4
|
import StrictEventEmitter from 'strict-event-emitter-types';
|
|
5
5
|
import { EventEmitter } from 'events';
|
|
@@ -7,13 +7,13 @@ import { Commitment, PublicKey } from '@solana/web3.js';
|
|
|
7
7
|
import { UserStatsAccount } from '../types';
|
|
8
8
|
export declare class WebSocketUserStatsAccountSubscriber implements UserStatsAccountSubscriber {
|
|
9
9
|
isSubscribed: boolean;
|
|
10
|
-
|
|
10
|
+
resubOpts?: ResubOpts;
|
|
11
11
|
commitment?: Commitment;
|
|
12
12
|
program: Program;
|
|
13
13
|
eventEmitter: StrictEventEmitter<EventEmitter, UserStatsAccountEvents>;
|
|
14
14
|
userStatsAccountPublicKey: PublicKey;
|
|
15
15
|
userStatsAccountSubscriber: AccountSubscriber<UserStatsAccount>;
|
|
16
|
-
constructor(program: Program, userStatsAccountPublicKey: PublicKey,
|
|
16
|
+
constructor(program: Program, userStatsAccountPublicKey: PublicKey, resubOpts?: ResubOpts, commitment?: Commitment);
|
|
17
17
|
subscribe(userStatsAccount?: UserStatsAccount): Promise<boolean>;
|
|
18
18
|
fetch(): Promise<void>;
|
|
19
19
|
unsubscribe(): Promise<void>;
|
|
@@ -5,19 +5,19 @@ const types_1 = require("./types");
|
|
|
5
5
|
const events_1 = require("events");
|
|
6
6
|
const webSocketAccountSubscriber_1 = require("./webSocketAccountSubscriber");
|
|
7
7
|
class WebSocketUserStatsAccountSubscriber {
|
|
8
|
-
constructor(program, userStatsAccountPublicKey,
|
|
8
|
+
constructor(program, userStatsAccountPublicKey, resubOpts, commitment) {
|
|
9
9
|
this.isSubscribed = false;
|
|
10
10
|
this.program = program;
|
|
11
11
|
this.userStatsAccountPublicKey = userStatsAccountPublicKey;
|
|
12
12
|
this.eventEmitter = new events_1.EventEmitter();
|
|
13
|
-
this.
|
|
13
|
+
this.resubOpts = resubOpts;
|
|
14
14
|
this.commitment = commitment;
|
|
15
15
|
}
|
|
16
16
|
async subscribe(userStatsAccount) {
|
|
17
17
|
if (this.isSubscribed) {
|
|
18
18
|
return true;
|
|
19
19
|
}
|
|
20
|
-
this.userStatsAccountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('userStats', this.program, this.userStatsAccountPublicKey, undefined, this.
|
|
20
|
+
this.userStatsAccountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('userStats', this.program, this.userStatsAccountPublicKey, undefined, this.resubOpts, this.commitment);
|
|
21
21
|
if (userStatsAccount) {
|
|
22
22
|
this.userStatsAccountSubscriber.setData(userStatsAccount);
|
|
23
23
|
}
|