@drift-labs/sdk 2.6.0 → 2.8.0-beta.0
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/bulkAccountLoader.d.ts +1 -3
- package/lib/accounts/bulkAccountLoader.js +30 -36
- package/lib/accounts/pollingDriftClientAccountSubscriber.d.ts +2 -2
- package/lib/accounts/pollingDriftClientAccountSubscriber.js +9 -9
- package/lib/accounts/pollingOracleAccountSubscriber.d.ts +1 -1
- package/lib/accounts/pollingOracleAccountSubscriber.js +3 -3
- package/lib/accounts/pollingTokenAccountSubscriber.d.ts +1 -1
- package/lib/accounts/pollingTokenAccountSubscriber.js +3 -3
- package/lib/accounts/pollingUserAccountSubscriber.js +1 -1
- package/lib/accounts/pollingUserStatsAccountSubscriber.js +1 -1
- package/lib/accounts/types.d.ts +0 -1
- package/lib/factory/bigNum.js +9 -7
- package/lib/idl/drift.json +1 -1
- package/lib/serum/serumSubscriber.js +2 -2
- package/package.json +1 -2
- package/src/accounts/bulkAccountLoader.ts +36 -42
- package/src/accounts/pollingDriftClientAccountSubscriber.ts +9 -9
- package/src/accounts/pollingOracleAccountSubscriber.ts +3 -3
- package/src/accounts/pollingTokenAccountSubscriber.ts +3 -3
- package/src/accounts/pollingUserAccountSubscriber.ts +1 -1
- package/src/accounts/pollingUserStatsAccountSubscriber.ts +1 -1
- package/src/factory/bigNum.ts +11 -8
- package/src/idl/drift.json +1 -1
- package/src/serum/serumSubscriber.ts +2 -2
- package/tests/amm/test.ts +197 -190
- package/tests/bn/test.ts +10 -0
- package/src/assert/assert.js +0 -9
- package/src/examples/makeTradeExample.js +0 -157
- package/src/token/index.js +0 -38
- package/src/tx/types.js +0 -2
- package/src/tx/utils.js +0 -17
- package/src/util/computeUnits.js +0 -27
- package/src/util/getTokenAddress.js +0 -9
- package/src/util/promiseTimeout.js +0 -14
- package/src/util/tps.js +0 -27
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { Commitment, Connection, PublicKey } from '@solana/web3.js';
|
|
3
3
|
import { BufferAndSlot } from './types';
|
|
4
|
-
import { Mutex } from 'async-mutex';
|
|
5
4
|
declare type AccountToLoad = {
|
|
6
5
|
publicKey: PublicKey;
|
|
7
6
|
callbacks: Map<string, (buffer: Buffer, slot: number) => void>;
|
|
@@ -15,12 +14,11 @@ export declare class BulkAccountLoader {
|
|
|
15
14
|
errorCallbacks: Map<string, (e: any) => void>;
|
|
16
15
|
intervalId?: NodeJS.Timer;
|
|
17
16
|
loadPromise?: Promise<void>;
|
|
18
|
-
loadPromiseLock: Mutex;
|
|
19
17
|
loadPromiseResolver: () => void;
|
|
20
18
|
lastTimeLoadingPromiseCleared: number;
|
|
21
19
|
mostRecentSlot: number;
|
|
22
20
|
constructor(connection: Connection, commitment: Commitment, pollingFrequency: number);
|
|
23
|
-
addAccount(publicKey: PublicKey, callback: (buffer: Buffer, slot: number) => void): string
|
|
21
|
+
addAccount(publicKey: PublicKey, callback: (buffer: Buffer, slot: number) => void): Promise<string>;
|
|
24
22
|
removeAccount(publicKey: PublicKey, callbackId: string): void;
|
|
25
23
|
addErrorCallbacks(callback: (error: Error) => void): string;
|
|
26
24
|
removeErrorCallbacks(callbackId: string): void;
|
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.BulkAccountLoader = void 0;
|
|
4
4
|
const uuid_1 = require("uuid");
|
|
5
5
|
const promiseTimeout_1 = require("../util/promiseTimeout");
|
|
6
|
-
const async_mutex_1 = require("async-mutex");
|
|
7
6
|
const GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE = 99;
|
|
8
7
|
const oneMinute = 60 * 1000;
|
|
9
8
|
class BulkAccountLoader {
|
|
@@ -11,14 +10,13 @@ class BulkAccountLoader {
|
|
|
11
10
|
this.accountsToLoad = new Map();
|
|
12
11
|
this.bufferAndSlotMap = new Map();
|
|
13
12
|
this.errorCallbacks = new Map();
|
|
14
|
-
this.loadPromiseLock = new async_mutex_1.Mutex();
|
|
15
13
|
this.lastTimeLoadingPromiseCleared = Date.now();
|
|
16
14
|
this.mostRecentSlot = 0;
|
|
17
15
|
this.connection = connection;
|
|
18
16
|
this.commitment = commitment;
|
|
19
17
|
this.pollingFrequency = pollingFrequency;
|
|
20
18
|
}
|
|
21
|
-
addAccount(publicKey, callback) {
|
|
19
|
+
async addAccount(publicKey, callback) {
|
|
22
20
|
const existingSize = this.accountsToLoad.size;
|
|
23
21
|
const callbackId = (0, uuid_1.v4)();
|
|
24
22
|
const existingAccountToLoad = this.accountsToLoad.get(publicKey.toString());
|
|
@@ -37,10 +35,8 @@ class BulkAccountLoader {
|
|
|
37
35
|
if (existingSize === 0) {
|
|
38
36
|
this.startPolling();
|
|
39
37
|
}
|
|
40
|
-
//
|
|
41
|
-
this.
|
|
42
|
-
this.loadPromise = undefined;
|
|
43
|
-
});
|
|
38
|
+
// resolve the current loadPromise in case client wants to call load
|
|
39
|
+
await this.loadPromise;
|
|
44
40
|
return callbackId;
|
|
45
41
|
}
|
|
46
42
|
removeAccount(publicKey, callbackId) {
|
|
@@ -70,38 +66,36 @@ class BulkAccountLoader {
|
|
|
70
66
|
.map((begin) => array.slice(begin, begin + size));
|
|
71
67
|
}
|
|
72
68
|
async load() {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if (now - this.lastTimeLoadingPromiseCleared > oneMinute) {
|
|
77
|
-
this.loadPromise = undefined;
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
return this.loadPromise;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
this.loadPromise = new Promise((resolver) => {
|
|
84
|
-
this.loadPromiseResolver = resolver;
|
|
85
|
-
});
|
|
86
|
-
this.lastTimeLoadingPromiseCleared = Date.now();
|
|
87
|
-
try {
|
|
88
|
-
const chunks = this.chunks(Array.from(this.accountsToLoad.values()), GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE);
|
|
89
|
-
await Promise.all(chunks.map((chunk) => {
|
|
90
|
-
return this.loadChunk(chunk);
|
|
91
|
-
}));
|
|
92
|
-
}
|
|
93
|
-
catch (e) {
|
|
94
|
-
console.error(`Error in bulkAccountLoader.load()`);
|
|
95
|
-
console.error(e);
|
|
96
|
-
for (const [_, callback] of this.errorCallbacks) {
|
|
97
|
-
callback(e);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
finally {
|
|
101
|
-
this.loadPromiseResolver();
|
|
69
|
+
if (this.loadPromise) {
|
|
70
|
+
const now = Date.now();
|
|
71
|
+
if (now - this.lastTimeLoadingPromiseCleared > oneMinute) {
|
|
102
72
|
this.loadPromise = undefined;
|
|
103
73
|
}
|
|
74
|
+
else {
|
|
75
|
+
return this.loadPromise;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
this.loadPromise = new Promise((resolver) => {
|
|
79
|
+
this.loadPromiseResolver = resolver;
|
|
104
80
|
});
|
|
81
|
+
this.lastTimeLoadingPromiseCleared = Date.now();
|
|
82
|
+
try {
|
|
83
|
+
const chunks = this.chunks(Array.from(this.accountsToLoad.values()), GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE);
|
|
84
|
+
await Promise.all(chunks.map((chunk) => {
|
|
85
|
+
return this.loadChunk(chunk);
|
|
86
|
+
}));
|
|
87
|
+
}
|
|
88
|
+
catch (e) {
|
|
89
|
+
console.error(`Error in bulkAccountLoader.load()`);
|
|
90
|
+
console.error(e);
|
|
91
|
+
for (const [_, callback] of this.errorCallbacks) {
|
|
92
|
+
callback(e);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
finally {
|
|
96
|
+
this.loadPromiseResolver();
|
|
97
|
+
this.loadPromise = undefined;
|
|
98
|
+
}
|
|
105
99
|
}
|
|
106
100
|
async loadChunk(accountsToLoad) {
|
|
107
101
|
if (accountsToLoad.length === 0) {
|
|
@@ -38,8 +38,8 @@ export declare class PollingDriftClientAccountSubscriber implements DriftClientA
|
|
|
38
38
|
updateOraclesToPoll(): boolean;
|
|
39
39
|
addOracleToPoll(oracleInfo: OracleInfo): boolean;
|
|
40
40
|
addToAccountLoader(): Promise<void>;
|
|
41
|
-
addAccountToAccountLoader(accountToPoll: AccountToPoll): void
|
|
42
|
-
addOracleToAccountLoader(oracleToPoll: OraclesToPoll): void
|
|
41
|
+
addAccountToAccountLoader(accountToPoll: AccountToPoll): Promise<void>;
|
|
42
|
+
addOracleToAccountLoader(oracleToPoll: OraclesToPoll): Promise<void>;
|
|
43
43
|
fetch(): Promise<void>;
|
|
44
44
|
didSubscriptionSucceed(): boolean;
|
|
45
45
|
unsubscribe(): Promise<void>;
|
|
@@ -116,17 +116,17 @@ class PollingDriftClientAccountSubscriber {
|
|
|
116
116
|
}
|
|
117
117
|
async addToAccountLoader() {
|
|
118
118
|
for (const [_, accountToPoll] of this.accountsToPoll) {
|
|
119
|
-
this.addAccountToAccountLoader(accountToPoll);
|
|
119
|
+
await this.addAccountToAccountLoader(accountToPoll);
|
|
120
120
|
}
|
|
121
121
|
for (const [_, oracleToPoll] of this.oraclesToPoll) {
|
|
122
|
-
this.addOracleToAccountLoader(oracleToPoll);
|
|
122
|
+
await this.addOracleToAccountLoader(oracleToPoll);
|
|
123
123
|
}
|
|
124
124
|
this.errorCallbackId = this.accountLoader.addErrorCallbacks((error) => {
|
|
125
125
|
this.eventEmitter.emit('error', error);
|
|
126
126
|
});
|
|
127
127
|
}
|
|
128
|
-
addAccountToAccountLoader(accountToPoll) {
|
|
129
|
-
accountToPoll.callbackId = this.accountLoader.addAccount(accountToPoll.publicKey, (buffer, slot) => {
|
|
128
|
+
async addAccountToAccountLoader(accountToPoll) {
|
|
129
|
+
accountToPoll.callbackId = await this.accountLoader.addAccount(accountToPoll.publicKey, (buffer, slot) => {
|
|
130
130
|
if (!buffer)
|
|
131
131
|
return;
|
|
132
132
|
const account = this.program.account[accountToPoll.key].coder.accounts.decode((0, utils_1.capitalize)(accountToPoll.key), buffer);
|
|
@@ -148,9 +148,9 @@ class PollingDriftClientAccountSubscriber {
|
|
|
148
148
|
}
|
|
149
149
|
});
|
|
150
150
|
}
|
|
151
|
-
addOracleToAccountLoader(oracleToPoll) {
|
|
151
|
+
async addOracleToAccountLoader(oracleToPoll) {
|
|
152
152
|
const oracleClient = this.oracleClientCache.get(oracleToPoll.source, this.program.provider.connection);
|
|
153
|
-
oracleToPoll.callbackId = this.accountLoader.addAccount(oracleToPoll.publicKey, (buffer, slot) => {
|
|
153
|
+
oracleToPoll.callbackId = await this.accountLoader.addAccount(oracleToPoll.publicKey, (buffer, slot) => {
|
|
154
154
|
if (!buffer)
|
|
155
155
|
return;
|
|
156
156
|
const oraclePriceData = oracleClient.getOraclePriceDataFromBuffer(buffer);
|
|
@@ -216,13 +216,13 @@ class PollingDriftClientAccountSubscriber {
|
|
|
216
216
|
async addSpotMarket(marketIndex) {
|
|
217
217
|
await this.addSpotMarketAccountToPoll(marketIndex);
|
|
218
218
|
const accountToPoll = this.accountsToPoll.get(marketIndex.toString());
|
|
219
|
-
this.addAccountToAccountLoader(accountToPoll);
|
|
219
|
+
await this.addAccountToAccountLoader(accountToPoll);
|
|
220
220
|
return true;
|
|
221
221
|
}
|
|
222
222
|
async addPerpMarket(marketIndex) {
|
|
223
223
|
await this.addPerpMarketAccountToPoll(marketIndex);
|
|
224
224
|
const accountToPoll = this.accountsToPoll.get(marketIndex.toString());
|
|
225
|
-
this.addAccountToAccountLoader(accountToPoll);
|
|
225
|
+
await this.addAccountToAccountLoader(accountToPoll);
|
|
226
226
|
return true;
|
|
227
227
|
}
|
|
228
228
|
async addOracle(oracleInfo) {
|
|
@@ -231,7 +231,7 @@ class PollingDriftClientAccountSubscriber {
|
|
|
231
231
|
}
|
|
232
232
|
this.addOracleToPoll(oracleInfo);
|
|
233
233
|
const oracleToPoll = this.oraclesToPoll.get(oracleInfo.publicKey.toString());
|
|
234
|
-
this.addOracleToAccountLoader(oracleToPoll);
|
|
234
|
+
await this.addOracleToAccountLoader(oracleToPoll);
|
|
235
235
|
return true;
|
|
236
236
|
}
|
|
237
237
|
assertIsSubscribed() {
|
|
@@ -18,7 +18,7 @@ export declare class PollingOracleAccountSubscriber implements OracleAccountSubs
|
|
|
18
18
|
oraclePriceData?: DataAndSlot<OraclePriceData>;
|
|
19
19
|
constructor(publicKey: PublicKey, oracleClient: OracleClient, accountLoader: BulkAccountLoader);
|
|
20
20
|
subscribe(): Promise<boolean>;
|
|
21
|
-
addToAccountLoader(): void
|
|
21
|
+
addToAccountLoader(): Promise<void>;
|
|
22
22
|
fetch(): Promise<void>;
|
|
23
23
|
unsubscribe(): Promise<void>;
|
|
24
24
|
assertIsSubscribed(): void;
|
|
@@ -15,7 +15,7 @@ class PollingOracleAccountSubscriber {
|
|
|
15
15
|
if (this.isSubscribed) {
|
|
16
16
|
return true;
|
|
17
17
|
}
|
|
18
|
-
this.addToAccountLoader();
|
|
18
|
+
await this.addToAccountLoader();
|
|
19
19
|
let subscriptionSucceeded = false;
|
|
20
20
|
let retries = 0;
|
|
21
21
|
while (!subscriptionSucceeded && retries < 5) {
|
|
@@ -29,11 +29,11 @@ class PollingOracleAccountSubscriber {
|
|
|
29
29
|
this.isSubscribed = subscriptionSucceeded;
|
|
30
30
|
return subscriptionSucceeded;
|
|
31
31
|
}
|
|
32
|
-
addToAccountLoader() {
|
|
32
|
+
async addToAccountLoader() {
|
|
33
33
|
if (this.callbackId) {
|
|
34
34
|
return;
|
|
35
35
|
}
|
|
36
|
-
this.callbackId = this.accountLoader.addAccount(this.publicKey, async (buffer, slot) => {
|
|
36
|
+
this.callbackId = await this.accountLoader.addAccount(this.publicKey, async (buffer, slot) => {
|
|
37
37
|
const oraclePriceData = await this.oracleClient.getOraclePriceDataFromBuffer(buffer);
|
|
38
38
|
this.oraclePriceData = { data: oraclePriceData, slot };
|
|
39
39
|
// @ts-ignore
|
|
@@ -17,7 +17,7 @@ export declare class PollingTokenAccountSubscriber implements TokenAccountSubscr
|
|
|
17
17
|
tokenAccountAndSlot?: DataAndSlot<AccountInfo>;
|
|
18
18
|
constructor(publicKey: PublicKey, accountLoader: BulkAccountLoader);
|
|
19
19
|
subscribe(): Promise<boolean>;
|
|
20
|
-
addToAccountLoader(): void
|
|
20
|
+
addToAccountLoader(): Promise<void>;
|
|
21
21
|
fetch(): Promise<void>;
|
|
22
22
|
unsubscribe(): Promise<void>;
|
|
23
23
|
assertIsSubscribed(): void;
|
|
@@ -15,7 +15,7 @@ class PollingTokenAccountSubscriber {
|
|
|
15
15
|
if (this.isSubscribed) {
|
|
16
16
|
return true;
|
|
17
17
|
}
|
|
18
|
-
this.addToAccountLoader();
|
|
18
|
+
await this.addToAccountLoader();
|
|
19
19
|
let subscriptionSucceeded = false;
|
|
20
20
|
let retries = 0;
|
|
21
21
|
while (!subscriptionSucceeded && retries < 5) {
|
|
@@ -29,11 +29,11 @@ class PollingTokenAccountSubscriber {
|
|
|
29
29
|
this.isSubscribed = subscriptionSucceeded;
|
|
30
30
|
return subscriptionSucceeded;
|
|
31
31
|
}
|
|
32
|
-
addToAccountLoader() {
|
|
32
|
+
async addToAccountLoader() {
|
|
33
33
|
if (this.callbackId) {
|
|
34
34
|
return;
|
|
35
35
|
}
|
|
36
|
-
this.callbackId = this.accountLoader.addAccount(this.publicKey, (buffer, slot) => {
|
|
36
|
+
this.callbackId = await this.accountLoader.addAccount(this.publicKey, (buffer, slot) => {
|
|
37
37
|
const tokenAccount = (0, token_1.parseTokenAccount)(buffer);
|
|
38
38
|
this.tokenAccountAndSlot = { data: tokenAccount, slot };
|
|
39
39
|
// @ts-ignore
|
|
@@ -35,7 +35,7 @@ class PollingUserAccountSubscriber {
|
|
|
35
35
|
eventType: 'userAccountUpdate',
|
|
36
36
|
});
|
|
37
37
|
for (const [_, accountToPoll] of this.accountsToPoll) {
|
|
38
|
-
accountToPoll.callbackId = this.accountLoader.addAccount(accountToPoll.publicKey, (buffer, slot) => {
|
|
38
|
+
accountToPoll.callbackId = await this.accountLoader.addAccount(accountToPoll.publicKey, (buffer, slot) => {
|
|
39
39
|
if (!buffer) {
|
|
40
40
|
return;
|
|
41
41
|
}
|
|
@@ -35,7 +35,7 @@ class PollingUserStatsAccountSubscriber {
|
|
|
35
35
|
eventType: 'userStatsAccountUpdate',
|
|
36
36
|
});
|
|
37
37
|
for (const [_, accountToPoll] of this.accountsToPoll) {
|
|
38
|
-
accountToPoll.callbackId = this.accountLoader.addAccount(accountToPoll.publicKey, (buffer, slot) => {
|
|
38
|
+
accountToPoll.callbackId = await this.accountLoader.addAccount(accountToPoll.publicKey, (buffer, slot) => {
|
|
39
39
|
if (!buffer) {
|
|
40
40
|
return;
|
|
41
41
|
}
|
package/lib/accounts/types.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
/// <reference types="node" />
|
|
3
2
|
import { SpotMarketAccount, PerpMarketAccount, OracleSource, StateAccount, UserAccount, UserStatsAccount } from '../types';
|
|
4
3
|
import StrictEventEmitter from 'strict-event-emitter-types';
|
|
5
4
|
import { EventEmitter } from 'events';
|
package/lib/factory/bigNum.js
CHANGED
|
@@ -252,13 +252,14 @@ class BigNum {
|
|
|
252
252
|
if (rounded) {
|
|
253
253
|
return this.toRounded(fixedPrecision).toPrecision(fixedPrecision, trailingZeroes);
|
|
254
254
|
}
|
|
255
|
-
const
|
|
255
|
+
const isNeg = this.isNeg();
|
|
256
|
+
const printString = this.abs().print();
|
|
257
|
+
const thisString = this.abs().toString();
|
|
256
258
|
let precisionPrintString = printString.slice(0, fixedPrecision + 1);
|
|
257
|
-
const thisString = this.toString();
|
|
258
259
|
if (!printString.includes(BigNum.delim) &&
|
|
259
260
|
thisString.length < fixedPrecision) {
|
|
260
261
|
const precisionMismatch = fixedPrecision - thisString.length;
|
|
261
|
-
return BigNum.from(thisString + this.getZeroes(precisionMismatch), precisionMismatch).toPrecision(fixedPrecision, trailingZeroes);
|
|
262
|
+
return BigNum.from((isNeg ? '-' : '') + thisString + this.getZeroes(precisionMismatch), precisionMismatch).toPrecision(fixedPrecision, trailingZeroes);
|
|
262
263
|
}
|
|
263
264
|
if (!precisionPrintString.includes(BigNum.delim) ||
|
|
264
265
|
precisionPrintString[precisionPrintString.length - 1] === BigNum.delim) {
|
|
@@ -298,7 +299,7 @@ class BigNum {
|
|
|
298
299
|
}
|
|
299
300
|
}
|
|
300
301
|
}
|
|
301
|
-
return precisionPrintString
|
|
302
|
+
return `${isNeg ? '-' : ''}${precisionPrintString}`;
|
|
302
303
|
}
|
|
303
304
|
toTradePrecision(rounded = false) {
|
|
304
305
|
return this.toPrecision(6, true, rounded);
|
|
@@ -333,7 +334,8 @@ class BigNum {
|
|
|
333
334
|
if (rounded) {
|
|
334
335
|
return this.toRounded(precision).toMillified(precision);
|
|
335
336
|
}
|
|
336
|
-
const
|
|
337
|
+
const isNeg = this.isNeg();
|
|
338
|
+
const stringVal = this.abs().print();
|
|
337
339
|
const [leftSide] = stringVal.split(BigNum.delim);
|
|
338
340
|
if (!leftSide) {
|
|
339
341
|
return this.shift(new anchor_1.BN(precision)).toPrecision(precision, true);
|
|
@@ -362,7 +364,7 @@ class BigNum {
|
|
|
362
364
|
else {
|
|
363
365
|
leadString = `${leadDigits.slice(0, decimalLocation)}${BigNum.delim}${leadDigits.slice(decimalLocation)}`;
|
|
364
366
|
}
|
|
365
|
-
return `${leadString}${unit}`;
|
|
367
|
+
return `${isNeg ? '-' : ''}${leadString}${unit}`;
|
|
366
368
|
}
|
|
367
369
|
toJSON() {
|
|
368
370
|
return {
|
|
@@ -426,7 +428,7 @@ class BigNum {
|
|
|
426
428
|
}
|
|
427
429
|
const sides = val.split(BigNum.delim);
|
|
428
430
|
const rightSide = sides[1];
|
|
429
|
-
const leftSide = sides[0].replace(/\
|
|
431
|
+
const leftSide = sides[0].replace(/\s/g, '');
|
|
430
432
|
const bnInput = `${leftSide !== null && leftSide !== void 0 ? leftSide : ''}${rightSide !== null && rightSide !== void 0 ? rightSide : ''}`;
|
|
431
433
|
const rawBn = new anchor_1.BN(bnInput);
|
|
432
434
|
const rightSideLength = (_a = rightSide === null || rightSide === void 0 ? void 0 : rightSide.length) !== null && _a !== void 0 ? _a : 0;
|
package/lib/idl/drift.json
CHANGED
|
@@ -18,13 +18,13 @@ class SerumSubscriber {
|
|
|
18
18
|
this.market = await serum_1.Market.load(this.connection, this.marketAddress, undefined, this.programId);
|
|
19
19
|
this.asksAddress = this.market.asksAddress;
|
|
20
20
|
this.asks = await this.market.loadAsks(this.connection);
|
|
21
|
-
this.asksCallbackId = this.accountLoader.addAccount(this.asksAddress, (buffer, slot) => {
|
|
21
|
+
this.asksCallbackId = await this.accountLoader.addAccount(this.asksAddress, (buffer, slot) => {
|
|
22
22
|
this.lastAsksSlot = slot;
|
|
23
23
|
this.asks = serum_1.Orderbook.decode(this.market, buffer);
|
|
24
24
|
});
|
|
25
25
|
this.bidsAddress = this.market.bidsAddress;
|
|
26
26
|
this.bids = await this.market.loadBids(this.connection);
|
|
27
|
-
this.bidsCallbackId = this.accountLoader.addAccount(this.bidsAddress, (buffer, slot) => {
|
|
27
|
+
this.bidsCallbackId = await this.accountLoader.addAccount(this.bidsAddress, (buffer, slot) => {
|
|
28
28
|
this.lastBidsSlot = slot;
|
|
29
29
|
this.bids = serum_1.Orderbook.decode(this.market, buffer);
|
|
30
30
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@drift-labs/sdk",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.8.0-beta.0",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"types": "lib/index.d.ts",
|
|
6
6
|
"author": "crispheaney",
|
|
@@ -39,7 +39,6 @@
|
|
|
39
39
|
"@solana/spl-token": "^0.1.6",
|
|
40
40
|
"@solana/web3.js": "1.66.2",
|
|
41
41
|
"@switchboard-xyz/switchboard-v2": "^0.0.67",
|
|
42
|
-
"async-mutex": "^0.4.0",
|
|
43
42
|
"strict-event-emitter-types": "^2.0.0",
|
|
44
43
|
"uuid": "^8.3.2"
|
|
45
44
|
},
|
|
@@ -2,7 +2,6 @@ import { Commitment, Connection, PublicKey } from '@solana/web3.js';
|
|
|
2
2
|
import { v4 as uuidv4 } from 'uuid';
|
|
3
3
|
import { BufferAndSlot } from './types';
|
|
4
4
|
import { promiseTimeout } from '../util/promiseTimeout';
|
|
5
|
-
import { Mutex } from 'async-mutex';
|
|
6
5
|
|
|
7
6
|
type AccountToLoad = {
|
|
8
7
|
publicKey: PublicKey;
|
|
@@ -23,7 +22,6 @@ export class BulkAccountLoader {
|
|
|
23
22
|
intervalId?: NodeJS.Timer;
|
|
24
23
|
// to handle clients spamming load
|
|
25
24
|
loadPromise?: Promise<void>;
|
|
26
|
-
loadPromiseLock: Mutex = new Mutex();
|
|
27
25
|
loadPromiseResolver: () => void;
|
|
28
26
|
lastTimeLoadingPromiseCleared = Date.now();
|
|
29
27
|
mostRecentSlot = 0;
|
|
@@ -38,10 +36,10 @@ export class BulkAccountLoader {
|
|
|
38
36
|
this.pollingFrequency = pollingFrequency;
|
|
39
37
|
}
|
|
40
38
|
|
|
41
|
-
public addAccount(
|
|
39
|
+
public async addAccount(
|
|
42
40
|
publicKey: PublicKey,
|
|
43
41
|
callback: (buffer: Buffer, slot: number) => void
|
|
44
|
-
): string {
|
|
42
|
+
): Promise<string> {
|
|
45
43
|
const existingSize = this.accountsToLoad.size;
|
|
46
44
|
|
|
47
45
|
const callbackId = uuidv4();
|
|
@@ -65,10 +63,8 @@ export class BulkAccountLoader {
|
|
|
65
63
|
this.startPolling();
|
|
66
64
|
}
|
|
67
65
|
|
|
68
|
-
//
|
|
69
|
-
this.
|
|
70
|
-
this.loadPromise = undefined;
|
|
71
|
-
});
|
|
66
|
+
// resolve the current loadPromise in case client wants to call load
|
|
67
|
+
await this.loadPromise;
|
|
72
68
|
|
|
73
69
|
return callbackId;
|
|
74
70
|
}
|
|
@@ -105,43 +101,41 @@ export class BulkAccountLoader {
|
|
|
105
101
|
}
|
|
106
102
|
|
|
107
103
|
public async load(): Promise<void> {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
if (now - this.lastTimeLoadingPromiseCleared > oneMinute) {
|
|
112
|
-
this.loadPromise = undefined;
|
|
113
|
-
} else {
|
|
114
|
-
return this.loadPromise;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
this.loadPromise = new Promise((resolver) => {
|
|
119
|
-
this.loadPromiseResolver = resolver;
|
|
120
|
-
});
|
|
121
|
-
this.lastTimeLoadingPromiseCleared = Date.now();
|
|
122
|
-
|
|
123
|
-
try {
|
|
124
|
-
const chunks = this.chunks(
|
|
125
|
-
Array.from(this.accountsToLoad.values()),
|
|
126
|
-
GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE
|
|
127
|
-
);
|
|
128
|
-
|
|
129
|
-
await Promise.all(
|
|
130
|
-
chunks.map((chunk) => {
|
|
131
|
-
return this.loadChunk(chunk);
|
|
132
|
-
})
|
|
133
|
-
);
|
|
134
|
-
} catch (e) {
|
|
135
|
-
console.error(`Error in bulkAccountLoader.load()`);
|
|
136
|
-
console.error(e);
|
|
137
|
-
for (const [_, callback] of this.errorCallbacks) {
|
|
138
|
-
callback(e);
|
|
139
|
-
}
|
|
140
|
-
} finally {
|
|
141
|
-
this.loadPromiseResolver();
|
|
104
|
+
if (this.loadPromise) {
|
|
105
|
+
const now = Date.now();
|
|
106
|
+
if (now - this.lastTimeLoadingPromiseCleared > oneMinute) {
|
|
142
107
|
this.loadPromise = undefined;
|
|
108
|
+
} else {
|
|
109
|
+
return this.loadPromise;
|
|
143
110
|
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
this.loadPromise = new Promise((resolver) => {
|
|
114
|
+
this.loadPromiseResolver = resolver;
|
|
144
115
|
});
|
|
116
|
+
this.lastTimeLoadingPromiseCleared = Date.now();
|
|
117
|
+
|
|
118
|
+
try {
|
|
119
|
+
const chunks = this.chunks(
|
|
120
|
+
Array.from(this.accountsToLoad.values()),
|
|
121
|
+
GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
await Promise.all(
|
|
125
|
+
chunks.map((chunk) => {
|
|
126
|
+
return this.loadChunk(chunk);
|
|
127
|
+
})
|
|
128
|
+
);
|
|
129
|
+
} catch (e) {
|
|
130
|
+
console.error(`Error in bulkAccountLoader.load()`);
|
|
131
|
+
console.error(e);
|
|
132
|
+
for (const [_, callback] of this.errorCallbacks) {
|
|
133
|
+
callback(e);
|
|
134
|
+
}
|
|
135
|
+
} finally {
|
|
136
|
+
this.loadPromiseResolver();
|
|
137
|
+
this.loadPromise = undefined;
|
|
138
|
+
}
|
|
145
139
|
}
|
|
146
140
|
|
|
147
141
|
async loadChunk(accountsToLoad: AccountToLoad[]): Promise<void> {
|
|
@@ -194,11 +194,11 @@ export class PollingDriftClientAccountSubscriber
|
|
|
194
194
|
|
|
195
195
|
async addToAccountLoader(): Promise<void> {
|
|
196
196
|
for (const [_, accountToPoll] of this.accountsToPoll) {
|
|
197
|
-
this.addAccountToAccountLoader(accountToPoll);
|
|
197
|
+
await this.addAccountToAccountLoader(accountToPoll);
|
|
198
198
|
}
|
|
199
199
|
|
|
200
200
|
for (const [_, oracleToPoll] of this.oraclesToPoll) {
|
|
201
|
-
this.addOracleToAccountLoader(oracleToPoll);
|
|
201
|
+
await this.addOracleToAccountLoader(oracleToPoll);
|
|
202
202
|
}
|
|
203
203
|
|
|
204
204
|
this.errorCallbackId = this.accountLoader.addErrorCallbacks((error) => {
|
|
@@ -206,8 +206,8 @@ export class PollingDriftClientAccountSubscriber
|
|
|
206
206
|
});
|
|
207
207
|
}
|
|
208
208
|
|
|
209
|
-
addAccountToAccountLoader(accountToPoll: AccountToPoll): void {
|
|
210
|
-
accountToPoll.callbackId = this.accountLoader.addAccount(
|
|
209
|
+
async addAccountToAccountLoader(accountToPoll: AccountToPoll): Promise<void> {
|
|
210
|
+
accountToPoll.callbackId = await this.accountLoader.addAccount(
|
|
211
211
|
accountToPoll.publicKey,
|
|
212
212
|
(buffer: Buffer, slot: number) => {
|
|
213
213
|
if (!buffer) return;
|
|
@@ -236,13 +236,13 @@ export class PollingDriftClientAccountSubscriber
|
|
|
236
236
|
);
|
|
237
237
|
}
|
|
238
238
|
|
|
239
|
-
addOracleToAccountLoader(oracleToPoll: OraclesToPoll): void {
|
|
239
|
+
async addOracleToAccountLoader(oracleToPoll: OraclesToPoll): Promise<void> {
|
|
240
240
|
const oracleClient = this.oracleClientCache.get(
|
|
241
241
|
oracleToPoll.source,
|
|
242
242
|
this.program.provider.connection
|
|
243
243
|
);
|
|
244
244
|
|
|
245
|
-
oracleToPoll.callbackId = this.accountLoader.addAccount(
|
|
245
|
+
oracleToPoll.callbackId = await this.accountLoader.addAccount(
|
|
246
246
|
oracleToPoll.publicKey,
|
|
247
247
|
(buffer: Buffer, slot: number) => {
|
|
248
248
|
if (!buffer) return;
|
|
@@ -342,14 +342,14 @@ export class PollingDriftClientAccountSubscriber
|
|
|
342
342
|
async addSpotMarket(marketIndex: number): Promise<boolean> {
|
|
343
343
|
await this.addSpotMarketAccountToPoll(marketIndex);
|
|
344
344
|
const accountToPoll = this.accountsToPoll.get(marketIndex.toString());
|
|
345
|
-
this.addAccountToAccountLoader(accountToPoll);
|
|
345
|
+
await this.addAccountToAccountLoader(accountToPoll);
|
|
346
346
|
return true;
|
|
347
347
|
}
|
|
348
348
|
|
|
349
349
|
async addPerpMarket(marketIndex: number): Promise<boolean> {
|
|
350
350
|
await this.addPerpMarketAccountToPoll(marketIndex);
|
|
351
351
|
const accountToPoll = this.accountsToPoll.get(marketIndex.toString());
|
|
352
|
-
this.addAccountToAccountLoader(accountToPoll);
|
|
352
|
+
await this.addAccountToAccountLoader(accountToPoll);
|
|
353
353
|
return true;
|
|
354
354
|
}
|
|
355
355
|
|
|
@@ -362,7 +362,7 @@ export class PollingDriftClientAccountSubscriber
|
|
|
362
362
|
const oracleToPoll = this.oraclesToPoll.get(
|
|
363
363
|
oracleInfo.publicKey.toString()
|
|
364
364
|
);
|
|
365
|
-
this.addOracleToAccountLoader(oracleToPoll);
|
|
365
|
+
await this.addOracleToAccountLoader(oracleToPoll);
|
|
366
366
|
return true;
|
|
367
367
|
}
|
|
368
368
|
|
|
@@ -41,7 +41,7 @@ export class PollingOracleAccountSubscriber implements OracleAccountSubscriber {
|
|
|
41
41
|
return true;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
this.addToAccountLoader();
|
|
44
|
+
await this.addToAccountLoader();
|
|
45
45
|
|
|
46
46
|
let subscriptionSucceeded = false;
|
|
47
47
|
let retries = 0;
|
|
@@ -59,12 +59,12 @@ export class PollingOracleAccountSubscriber implements OracleAccountSubscriber {
|
|
|
59
59
|
return subscriptionSucceeded;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
addToAccountLoader(): void {
|
|
62
|
+
async addToAccountLoader(): Promise<void> {
|
|
63
63
|
if (this.callbackId) {
|
|
64
64
|
return;
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
this.callbackId = this.accountLoader.addAccount(
|
|
67
|
+
this.callbackId = await this.accountLoader.addAccount(
|
|
68
68
|
this.publicKey,
|
|
69
69
|
async (buffer, slot) => {
|
|
70
70
|
const oraclePriceData =
|
|
@@ -36,7 +36,7 @@ export class PollingTokenAccountSubscriber implements TokenAccountSubscriber {
|
|
|
36
36
|
return true;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
this.addToAccountLoader();
|
|
39
|
+
await this.addToAccountLoader();
|
|
40
40
|
let subscriptionSucceeded = false;
|
|
41
41
|
let retries = 0;
|
|
42
42
|
while (!subscriptionSucceeded && retries < 5) {
|
|
@@ -53,12 +53,12 @@ export class PollingTokenAccountSubscriber implements TokenAccountSubscriber {
|
|
|
53
53
|
return subscriptionSucceeded;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
addToAccountLoader(): void {
|
|
56
|
+
async addToAccountLoader(): Promise<void> {
|
|
57
57
|
if (this.callbackId) {
|
|
58
58
|
return;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
this.callbackId = this.accountLoader.addAccount(
|
|
61
|
+
this.callbackId = await this.accountLoader.addAccount(
|
|
62
62
|
this.publicKey,
|
|
63
63
|
(buffer, slot: number) => {
|
|
64
64
|
const tokenAccount = parseTokenAccount(buffer);
|
|
@@ -65,7 +65,7 @@ export class PollingUserAccountSubscriber implements UserAccountSubscriber {
|
|
|
65
65
|
});
|
|
66
66
|
|
|
67
67
|
for (const [_, accountToPoll] of this.accountsToPoll) {
|
|
68
|
-
accountToPoll.callbackId = this.accountLoader.addAccount(
|
|
68
|
+
accountToPoll.callbackId = await this.accountLoader.addAccount(
|
|
69
69
|
accountToPoll.publicKey,
|
|
70
70
|
(buffer, slot) => {
|
|
71
71
|
if (!buffer) {
|
|
@@ -68,7 +68,7 @@ export class PollingUserStatsAccountSubscriber
|
|
|
68
68
|
});
|
|
69
69
|
|
|
70
70
|
for (const [_, accountToPoll] of this.accountsToPoll) {
|
|
71
|
-
accountToPoll.callbackId = this.accountLoader.addAccount(
|
|
71
|
+
accountToPoll.callbackId = await this.accountLoader.addAccount(
|
|
72
72
|
accountToPoll.publicKey,
|
|
73
73
|
(buffer, slot) => {
|
|
74
74
|
if (!buffer) {
|