@drift-labs/sdk 2.95.0-beta.12 → 2.95.0-beta.13
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/webSocketDriftClientAccountSubscriber.d.ts +5 -0
- package/lib/accounts/webSocketDriftClientAccountSubscriber.js +43 -2
- package/lib/addresses/pda.d.ts +2 -0
- package/lib/addresses/pda.js +15 -1
- package/lib/config.d.ts +3 -0
- package/lib/config.js +2 -0
- package/package.json +1 -1
- package/src/accounts/webSocketDriftClientAccountSubscriber.ts +98 -7
- package/src/addresses/pda.ts +26 -0
- package/src/config.ts +8 -0
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.95.0-beta.
|
|
1
|
+
2.95.0-beta.13
|
|
@@ -25,11 +25,16 @@ export declare class WebSocketDriftClientAccountSubscriber implements DriftClien
|
|
|
25
25
|
spotMarketAccountSubscribers: Map<number, AccountSubscriber<SpotMarketAccount>>;
|
|
26
26
|
spotOracleMap: Map<number, PublicKey>;
|
|
27
27
|
oracleSubscribers: Map<string, AccountSubscriber<OraclePriceData>>;
|
|
28
|
+
initialPerpMarketAccountData: Map<number, PerpMarketAccount>;
|
|
29
|
+
initialSpotMarketAccountData: Map<number, SpotMarketAccount>;
|
|
30
|
+
initialOraclePriceData: Map<string, OraclePriceData>;
|
|
28
31
|
private isSubscribing;
|
|
29
32
|
private subscriptionPromise;
|
|
30
33
|
private subscriptionPromiseResolver;
|
|
31
34
|
constructor(program: Program, perpMarketIndexes: number[], spotMarketIndexes: number[], oracleInfos: OracleInfo[], shouldFindAllMarketsAndOracles: boolean, resubOpts?: ResubOpts, commitment?: Commitment);
|
|
32
35
|
subscribe(): Promise<boolean>;
|
|
36
|
+
setInitialData(): Promise<void>;
|
|
37
|
+
removeInitialData(): void;
|
|
33
38
|
subscribeToPerpMarketAccounts(): Promise<boolean>;
|
|
34
39
|
subscribeToPerpMarketAccount(marketIndex: number): Promise<boolean>;
|
|
35
40
|
subscribeToSpotMarketAccounts(): Promise<boolean>;
|
|
@@ -40,10 +40,13 @@ class WebSocketDriftClientAccountSubscriber {
|
|
|
40
40
|
this.subscriptionPromiseResolver = res;
|
|
41
41
|
});
|
|
42
42
|
if (this.shouldFindAllMarketsAndOracles) {
|
|
43
|
-
const { perpMarketIndexes, spotMarketIndexes, oracleInfos } = await (0, config_1.findAllMarketAndOracles)(this.program);
|
|
43
|
+
const { perpMarketIndexes, perpMarketAccounts, spotMarketIndexes, spotMarketAccounts, oracleInfos, } = await (0, config_1.findAllMarketAndOracles)(this.program);
|
|
44
44
|
this.perpMarketIndexes = perpMarketIndexes;
|
|
45
45
|
this.spotMarketIndexes = spotMarketIndexes;
|
|
46
46
|
this.oracleInfos = oracleInfos;
|
|
47
|
+
// front run and set the initial data here to save extra gma call in set initial data
|
|
48
|
+
this.initialPerpMarketAccountData = new Map(perpMarketAccounts.map((market) => [market.marketIndex, market]));
|
|
49
|
+
this.initialSpotMarketAccountData = new Map(spotMarketAccounts.map((market) => [market.marketIndex, market]));
|
|
47
50
|
}
|
|
48
51
|
const statePublicKey = await (0, pda_1.getDriftStateAccountPublicKey)(this.program.programId);
|
|
49
52
|
// create and activate main state account subscription
|
|
@@ -52,6 +55,8 @@ class WebSocketDriftClientAccountSubscriber {
|
|
|
52
55
|
this.eventEmitter.emit('stateAccountUpdate', data);
|
|
53
56
|
this.eventEmitter.emit('update');
|
|
54
57
|
});
|
|
58
|
+
// set initial data to avoid spamming getAccountInfo calls in webSocketAccountSubscriber
|
|
59
|
+
await this.setInitialData();
|
|
55
60
|
await Promise.all([
|
|
56
61
|
// subscribe to market accounts
|
|
57
62
|
this.subscribeToPerpMarketAccounts(),
|
|
@@ -65,8 +70,40 @@ class WebSocketDriftClientAccountSubscriber {
|
|
|
65
70
|
this.isSubscribing = false;
|
|
66
71
|
this.isSubscribed = true;
|
|
67
72
|
this.subscriptionPromiseResolver(true);
|
|
73
|
+
// delete initial data
|
|
74
|
+
this.removeInitialData();
|
|
68
75
|
return true;
|
|
69
76
|
}
|
|
77
|
+
async setInitialData() {
|
|
78
|
+
const connection = this.program.provider.connection;
|
|
79
|
+
if (!this.initialPerpMarketAccountData) {
|
|
80
|
+
const perpMarketPublicKeys = this.perpMarketIndexes.map((marketIndex) => (0, pda_1.getPerpMarketPublicKeySync)(this.program.programId, marketIndex));
|
|
81
|
+
const perpMarketAccountInfos = await connection.getMultipleAccountsInfo(perpMarketPublicKeys);
|
|
82
|
+
this.initialPerpMarketAccountData = new Map(perpMarketAccountInfos.map((accountInfo) => {
|
|
83
|
+
const perpMarket = this.program.coder.accounts.decode('PerpMarket', accountInfo.data);
|
|
84
|
+
return [perpMarket.marketIndex, perpMarket];
|
|
85
|
+
}));
|
|
86
|
+
}
|
|
87
|
+
if (!this.initialSpotMarketAccountData) {
|
|
88
|
+
const spotMarketPublicKeys = this.spotMarketIndexes.map((marketIndex) => (0, pda_1.getSpotMarketPublicKeySync)(this.program.programId, marketIndex));
|
|
89
|
+
const spotMarketAccountInfos = await connection.getMultipleAccountsInfo(spotMarketPublicKeys);
|
|
90
|
+
this.initialSpotMarketAccountData = new Map(spotMarketAccountInfos.map((accountInfo) => {
|
|
91
|
+
const spotMarket = this.program.coder.accounts.decode('SpotMarket', accountInfo.data);
|
|
92
|
+
return [spotMarket.marketIndex, spotMarket];
|
|
93
|
+
}));
|
|
94
|
+
}
|
|
95
|
+
const oracleAccountInfos = await connection.getMultipleAccountsInfo(this.oracleInfos.map((oracleInfo) => oracleInfo.publicKey));
|
|
96
|
+
this.initialOraclePriceData = new Map(this.oracleInfos.map((oracleInfo, i) => {
|
|
97
|
+
const oracleClient = this.oracleClientCache.get(oracleInfo.source, connection, this.program);
|
|
98
|
+
const oraclePriceData = oracleClient.getOraclePriceDataFromBuffer(oracleAccountInfos[i].data);
|
|
99
|
+
return [oracleInfo.publicKey.toString(), oraclePriceData];
|
|
100
|
+
}));
|
|
101
|
+
}
|
|
102
|
+
removeInitialData() {
|
|
103
|
+
this.initialPerpMarketAccountData = new Map();
|
|
104
|
+
this.initialSpotMarketAccountData = new Map();
|
|
105
|
+
this.initialOraclePriceData = new Map();
|
|
106
|
+
}
|
|
70
107
|
async subscribeToPerpMarketAccounts() {
|
|
71
108
|
await Promise.all(this.perpMarketIndexes.map((marketIndex) => this.subscribeToPerpMarketAccount(marketIndex)));
|
|
72
109
|
return true;
|
|
@@ -74,6 +111,7 @@ class WebSocketDriftClientAccountSubscriber {
|
|
|
74
111
|
async subscribeToPerpMarketAccount(marketIndex) {
|
|
75
112
|
const perpMarketPublicKey = await (0, pda_1.getPerpMarketPublicKey)(this.program.programId, marketIndex);
|
|
76
113
|
const accountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('perpMarket', this.program, perpMarketPublicKey, undefined, this.resubOpts, this.commitment);
|
|
114
|
+
accountSubscriber.setData(this.initialPerpMarketAccountData.get(marketIndex));
|
|
77
115
|
await accountSubscriber.subscribe((data) => {
|
|
78
116
|
this.eventEmitter.emit('perpMarketAccountUpdate', data);
|
|
79
117
|
this.eventEmitter.emit('update');
|
|
@@ -88,6 +126,7 @@ class WebSocketDriftClientAccountSubscriber {
|
|
|
88
126
|
async subscribeToSpotMarketAccount(marketIndex) {
|
|
89
127
|
const marketPublicKey = await (0, pda_1.getSpotMarketPublicKey)(this.program.programId, marketIndex);
|
|
90
128
|
const accountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('spotMarket', this.program, marketPublicKey, undefined, this.resubOpts, this.commitment);
|
|
129
|
+
accountSubscriber.setData(this.initialSpotMarketAccountData.get(marketIndex));
|
|
91
130
|
await accountSubscriber.subscribe((data) => {
|
|
92
131
|
this.eventEmitter.emit('spotMarketAccountUpdate', data);
|
|
93
132
|
this.eventEmitter.emit('update');
|
|
@@ -102,15 +141,17 @@ class WebSocketDriftClientAccountSubscriber {
|
|
|
102
141
|
return true;
|
|
103
142
|
}
|
|
104
143
|
async subscribeToOracle(oracleInfo) {
|
|
144
|
+
const oracleString = oracleInfo.publicKey.toString();
|
|
105
145
|
const client = this.oracleClientCache.get(oracleInfo.source, this.program.provider.connection, this.program);
|
|
106
146
|
const accountSubscriber = new webSocketAccountSubscriber_1.WebSocketAccountSubscriber('oracle', this.program, oracleInfo.publicKey, (buffer) => {
|
|
107
147
|
return client.getOraclePriceDataFromBuffer(buffer);
|
|
108
148
|
}, this.resubOpts, this.commitment);
|
|
149
|
+
accountSubscriber.setData(this.initialOraclePriceData.get(oracleString));
|
|
109
150
|
await accountSubscriber.subscribe((data) => {
|
|
110
151
|
this.eventEmitter.emit('oraclePriceUpdate', oracleInfo.publicKey, data);
|
|
111
152
|
this.eventEmitter.emit('update');
|
|
112
153
|
});
|
|
113
|
-
this.oracleSubscribers.set(
|
|
154
|
+
this.oracleSubscribers.set(oracleString, accountSubscriber);
|
|
114
155
|
return true;
|
|
115
156
|
}
|
|
116
157
|
async unsubscribeFromMarketAccounts() {
|
package/lib/addresses/pda.d.ts
CHANGED
|
@@ -9,7 +9,9 @@ export declare function getUserAccountPublicKey(programId: PublicKey, authority:
|
|
|
9
9
|
export declare function getUserAccountPublicKeySync(programId: PublicKey, authority: PublicKey, subAccountId?: number): PublicKey;
|
|
10
10
|
export declare function getUserStatsAccountPublicKey(programId: PublicKey, authority: PublicKey): PublicKey;
|
|
11
11
|
export declare function getPerpMarketPublicKey(programId: PublicKey, marketIndex: number): Promise<PublicKey>;
|
|
12
|
+
export declare function getPerpMarketPublicKeySync(programId: PublicKey, marketIndex: number): PublicKey;
|
|
12
13
|
export declare function getSpotMarketPublicKey(programId: PublicKey, marketIndex: number): Promise<PublicKey>;
|
|
14
|
+
export declare function getSpotMarketPublicKeySync(programId: PublicKey, marketIndex: number): PublicKey;
|
|
13
15
|
export declare function getSpotMarketVaultPublicKey(programId: PublicKey, marketIndex: number): Promise<PublicKey>;
|
|
14
16
|
export declare function getInsuranceFundVaultPublicKey(programId: PublicKey, marketIndex: number): Promise<PublicKey>;
|
|
15
17
|
export declare function getInsuranceFundStakeAccountPublicKey(programId: PublicKey, authority: PublicKey, marketIndex: number): PublicKey;
|
package/lib/addresses/pda.js
CHANGED
|
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.getTokenProgramForSpotMarket = exports.getPythPullOraclePublicKey = exports.getPrelaunchOraclePublicKey = exports.getProtocolIfSharesTransferConfigPublicKey = exports.getReferrerNamePublicKeySync = exports.getOpenbookV2FulfillmentConfigPublicKey = exports.getPhoenixFulfillmentConfigPublicKey = exports.getSerumFulfillmentConfigPublicKey = exports.getSerumSignerPublicKey = exports.getSerumOpenOrdersPublicKey = exports.getDriftSignerPublicKey = exports.getInsuranceFundStakeAccountPublicKey = exports.getInsuranceFundVaultPublicKey = exports.getSpotMarketVaultPublicKey = exports.getSpotMarketPublicKey = exports.getPerpMarketPublicKey = exports.getUserStatsAccountPublicKey = exports.getUserAccountPublicKeySync = exports.getUserAccountPublicKey = exports.getUserAccountPublicKeyAndNonce = exports.getDriftStateAccountPublicKey = exports.getDriftStateAccountPublicKeyAndNonce = void 0;
|
|
26
|
+
exports.getTokenProgramForSpotMarket = exports.getPythPullOraclePublicKey = exports.getPrelaunchOraclePublicKey = exports.getProtocolIfSharesTransferConfigPublicKey = exports.getReferrerNamePublicKeySync = exports.getOpenbookV2FulfillmentConfigPublicKey = exports.getPhoenixFulfillmentConfigPublicKey = exports.getSerumFulfillmentConfigPublicKey = exports.getSerumSignerPublicKey = exports.getSerumOpenOrdersPublicKey = exports.getDriftSignerPublicKey = exports.getInsuranceFundStakeAccountPublicKey = exports.getInsuranceFundVaultPublicKey = exports.getSpotMarketVaultPublicKey = exports.getSpotMarketPublicKeySync = exports.getSpotMarketPublicKey = exports.getPerpMarketPublicKeySync = exports.getPerpMarketPublicKey = exports.getUserStatsAccountPublicKey = exports.getUserAccountPublicKeySync = exports.getUserAccountPublicKey = exports.getUserAccountPublicKeyAndNonce = exports.getDriftStateAccountPublicKey = exports.getDriftStateAccountPublicKeyAndNonce = void 0;
|
|
27
27
|
const web3_js_1 = require("@solana/web3.js");
|
|
28
28
|
const anchor = __importStar(require("@coral-xyz/anchor"));
|
|
29
29
|
const spl_token_1 = require("@solana/spl-token");
|
|
@@ -69,6 +69,13 @@ async function getPerpMarketPublicKey(programId, marketIndex) {
|
|
|
69
69
|
], programId))[0];
|
|
70
70
|
}
|
|
71
71
|
exports.getPerpMarketPublicKey = getPerpMarketPublicKey;
|
|
72
|
+
function getPerpMarketPublicKeySync(programId, marketIndex) {
|
|
73
|
+
return web3_js_1.PublicKey.findProgramAddressSync([
|
|
74
|
+
Buffer.from(anchor.utils.bytes.utf8.encode('perp_market')),
|
|
75
|
+
new anchor.BN(marketIndex).toArrayLike(Buffer, 'le', 2),
|
|
76
|
+
], programId)[0];
|
|
77
|
+
}
|
|
78
|
+
exports.getPerpMarketPublicKeySync = getPerpMarketPublicKeySync;
|
|
72
79
|
async function getSpotMarketPublicKey(programId, marketIndex) {
|
|
73
80
|
return (await web3_js_1.PublicKey.findProgramAddress([
|
|
74
81
|
Buffer.from(anchor.utils.bytes.utf8.encode('spot_market')),
|
|
@@ -76,6 +83,13 @@ async function getSpotMarketPublicKey(programId, marketIndex) {
|
|
|
76
83
|
], programId))[0];
|
|
77
84
|
}
|
|
78
85
|
exports.getSpotMarketPublicKey = getSpotMarketPublicKey;
|
|
86
|
+
function getSpotMarketPublicKeySync(programId, marketIndex) {
|
|
87
|
+
return web3_js_1.PublicKey.findProgramAddressSync([
|
|
88
|
+
Buffer.from(anchor.utils.bytes.utf8.encode('spot_market')),
|
|
89
|
+
new anchor.BN(marketIndex).toArrayLike(Buffer, 'le', 2),
|
|
90
|
+
], programId)[0];
|
|
91
|
+
}
|
|
92
|
+
exports.getSpotMarketPublicKeySync = getSpotMarketPublicKeySync;
|
|
79
93
|
async function getSpotMarketVaultPublicKey(programId, marketIndex) {
|
|
80
94
|
return (await web3_js_1.PublicKey.findProgramAddress([
|
|
81
95
|
Buffer.from(anchor.utils.bytes.utf8.encode('spot_market_vault')),
|
package/lib/config.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { PerpMarketAccount, SpotMarketAccount } from '.';
|
|
1
2
|
import { PerpMarketConfig } from './constants/perpMarkets';
|
|
2
3
|
import { SpotMarketConfig } from './constants/spotMarkets';
|
|
3
4
|
import { OracleInfo } from './oracles/types';
|
|
@@ -44,7 +45,9 @@ export declare function getMarketsAndOraclesForSubscription(env: DriftEnv): {
|
|
|
44
45
|
};
|
|
45
46
|
export declare function findAllMarketAndOracles(program: Program): Promise<{
|
|
46
47
|
perpMarketIndexes: number[];
|
|
48
|
+
perpMarketAccounts: PerpMarketAccount[];
|
|
47
49
|
spotMarketIndexes: number[];
|
|
48
50
|
oracleInfos: OracleInfo[];
|
|
51
|
+
spotMarketAccounts: SpotMarketAccount[];
|
|
49
52
|
}>;
|
|
50
53
|
export {};
|
package/lib/config.js
CHANGED
|
@@ -106,7 +106,9 @@ async function findAllMarketAndOracles(program) {
|
|
|
106
106
|
}
|
|
107
107
|
return {
|
|
108
108
|
perpMarketIndexes,
|
|
109
|
+
perpMarketAccounts: perpMarketProgramAccounts.map((account) => account.account),
|
|
109
110
|
spotMarketIndexes,
|
|
111
|
+
spotMarketAccounts: spotMarketProgramAccounts.map((account) => account.account),
|
|
110
112
|
oracleInfos: Array.from(oracleInfos.values()),
|
|
111
113
|
};
|
|
112
114
|
}
|
package/package.json
CHANGED
|
@@ -13,6 +13,8 @@ import {
|
|
|
13
13
|
getDriftStateAccountPublicKey,
|
|
14
14
|
getSpotMarketPublicKey,
|
|
15
15
|
getPerpMarketPublicKey,
|
|
16
|
+
getPerpMarketPublicKeySync,
|
|
17
|
+
getSpotMarketPublicKeySync,
|
|
16
18
|
} from '../addresses/pda';
|
|
17
19
|
import { WebSocketAccountSubscriber } from './webSocketAccountSubscriber';
|
|
18
20
|
import { Commitment, PublicKey } from '@solana/web3.js';
|
|
@@ -50,6 +52,10 @@ export class WebSocketDriftClientAccountSubscriber
|
|
|
50
52
|
spotOracleMap = new Map<number, PublicKey>();
|
|
51
53
|
oracleSubscribers = new Map<string, AccountSubscriber<OraclePriceData>>();
|
|
52
54
|
|
|
55
|
+
initialPerpMarketAccountData: Map<number, PerpMarketAccount>;
|
|
56
|
+
initialSpotMarketAccountData: Map<number, SpotMarketAccount>;
|
|
57
|
+
initialOraclePriceData: Map<string, OraclePriceData>;
|
|
58
|
+
|
|
53
59
|
private isSubscribing = false;
|
|
54
60
|
private subscriptionPromise: Promise<boolean>;
|
|
55
61
|
private subscriptionPromiseResolver: (val: boolean) => void;
|
|
@@ -90,11 +96,23 @@ export class WebSocketDriftClientAccountSubscriber
|
|
|
90
96
|
});
|
|
91
97
|
|
|
92
98
|
if (this.shouldFindAllMarketsAndOracles) {
|
|
93
|
-
const {
|
|
94
|
-
|
|
99
|
+
const {
|
|
100
|
+
perpMarketIndexes,
|
|
101
|
+
perpMarketAccounts,
|
|
102
|
+
spotMarketIndexes,
|
|
103
|
+
spotMarketAccounts,
|
|
104
|
+
oracleInfos,
|
|
105
|
+
} = await findAllMarketAndOracles(this.program);
|
|
95
106
|
this.perpMarketIndexes = perpMarketIndexes;
|
|
96
107
|
this.spotMarketIndexes = spotMarketIndexes;
|
|
97
108
|
this.oracleInfos = oracleInfos;
|
|
109
|
+
// front run and set the initial data here to save extra gma call in set initial data
|
|
110
|
+
this.initialPerpMarketAccountData = new Map(
|
|
111
|
+
perpMarketAccounts.map((market) => [market.marketIndex, market])
|
|
112
|
+
);
|
|
113
|
+
this.initialSpotMarketAccountData = new Map(
|
|
114
|
+
spotMarketAccounts.map((market) => [market.marketIndex, market])
|
|
115
|
+
);
|
|
98
116
|
}
|
|
99
117
|
|
|
100
118
|
const statePublicKey = await getDriftStateAccountPublicKey(
|
|
@@ -115,6 +133,9 @@ export class WebSocketDriftClientAccountSubscriber
|
|
|
115
133
|
this.eventEmitter.emit('update');
|
|
116
134
|
});
|
|
117
135
|
|
|
136
|
+
// set initial data to avoid spamming getAccountInfo calls in webSocketAccountSubscriber
|
|
137
|
+
await this.setInitialData();
|
|
138
|
+
|
|
118
139
|
await Promise.all([
|
|
119
140
|
// subscribe to market accounts
|
|
120
141
|
this.subscribeToPerpMarketAccounts(),
|
|
@@ -132,9 +153,75 @@ export class WebSocketDriftClientAccountSubscriber
|
|
|
132
153
|
this.isSubscribed = true;
|
|
133
154
|
this.subscriptionPromiseResolver(true);
|
|
134
155
|
|
|
156
|
+
// delete initial data
|
|
157
|
+
this.removeInitialData();
|
|
158
|
+
|
|
135
159
|
return true;
|
|
136
160
|
}
|
|
137
161
|
|
|
162
|
+
async setInitialData(): Promise<void> {
|
|
163
|
+
const connection = this.program.provider.connection;
|
|
164
|
+
|
|
165
|
+
if (!this.initialPerpMarketAccountData) {
|
|
166
|
+
const perpMarketPublicKeys = this.perpMarketIndexes.map((marketIndex) =>
|
|
167
|
+
getPerpMarketPublicKeySync(this.program.programId, marketIndex)
|
|
168
|
+
);
|
|
169
|
+
const perpMarketAccountInfos = await connection.getMultipleAccountsInfo(
|
|
170
|
+
perpMarketPublicKeys
|
|
171
|
+
);
|
|
172
|
+
this.initialPerpMarketAccountData = new Map(
|
|
173
|
+
perpMarketAccountInfos.map((accountInfo) => {
|
|
174
|
+
const perpMarket = this.program.coder.accounts.decode(
|
|
175
|
+
'PerpMarket',
|
|
176
|
+
accountInfo.data
|
|
177
|
+
);
|
|
178
|
+
return [perpMarket.marketIndex, perpMarket];
|
|
179
|
+
})
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (!this.initialSpotMarketAccountData) {
|
|
184
|
+
const spotMarketPublicKeys = this.spotMarketIndexes.map((marketIndex) =>
|
|
185
|
+
getSpotMarketPublicKeySync(this.program.programId, marketIndex)
|
|
186
|
+
);
|
|
187
|
+
const spotMarketAccountInfos = await connection.getMultipleAccountsInfo(
|
|
188
|
+
spotMarketPublicKeys
|
|
189
|
+
);
|
|
190
|
+
this.initialSpotMarketAccountData = new Map(
|
|
191
|
+
spotMarketAccountInfos.map((accountInfo) => {
|
|
192
|
+
const spotMarket = this.program.coder.accounts.decode(
|
|
193
|
+
'SpotMarket',
|
|
194
|
+
accountInfo.data
|
|
195
|
+
);
|
|
196
|
+
return [spotMarket.marketIndex, spotMarket];
|
|
197
|
+
})
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const oracleAccountInfos = await connection.getMultipleAccountsInfo(
|
|
202
|
+
this.oracleInfos.map((oracleInfo) => oracleInfo.publicKey)
|
|
203
|
+
);
|
|
204
|
+
this.initialOraclePriceData = new Map(
|
|
205
|
+
this.oracleInfos.map((oracleInfo, i) => {
|
|
206
|
+
const oracleClient = this.oracleClientCache.get(
|
|
207
|
+
oracleInfo.source,
|
|
208
|
+
connection,
|
|
209
|
+
this.program
|
|
210
|
+
);
|
|
211
|
+
const oraclePriceData = oracleClient.getOraclePriceDataFromBuffer(
|
|
212
|
+
oracleAccountInfos[i].data
|
|
213
|
+
);
|
|
214
|
+
return [oracleInfo.publicKey.toString(), oraclePriceData];
|
|
215
|
+
})
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
removeInitialData() {
|
|
220
|
+
this.initialPerpMarketAccountData = new Map();
|
|
221
|
+
this.initialSpotMarketAccountData = new Map();
|
|
222
|
+
this.initialOraclePriceData = new Map();
|
|
223
|
+
}
|
|
224
|
+
|
|
138
225
|
async subscribeToPerpMarketAccounts(): Promise<boolean> {
|
|
139
226
|
await Promise.all(
|
|
140
227
|
this.perpMarketIndexes.map((marketIndex) =>
|
|
@@ -157,6 +244,9 @@ export class WebSocketDriftClientAccountSubscriber
|
|
|
157
244
|
this.resubOpts,
|
|
158
245
|
this.commitment
|
|
159
246
|
);
|
|
247
|
+
accountSubscriber.setData(
|
|
248
|
+
this.initialPerpMarketAccountData.get(marketIndex)
|
|
249
|
+
);
|
|
160
250
|
await accountSubscriber.subscribe((data: PerpMarketAccount) => {
|
|
161
251
|
this.eventEmitter.emit('perpMarketAccountUpdate', data);
|
|
162
252
|
this.eventEmitter.emit('update');
|
|
@@ -187,6 +277,9 @@ export class WebSocketDriftClientAccountSubscriber
|
|
|
187
277
|
this.resubOpts,
|
|
188
278
|
this.commitment
|
|
189
279
|
);
|
|
280
|
+
accountSubscriber.setData(
|
|
281
|
+
this.initialSpotMarketAccountData.get(marketIndex)
|
|
282
|
+
);
|
|
190
283
|
await accountSubscriber.subscribe((data: SpotMarketAccount) => {
|
|
191
284
|
this.eventEmitter.emit('spotMarketAccountUpdate', data);
|
|
192
285
|
this.eventEmitter.emit('update');
|
|
@@ -206,6 +299,7 @@ export class WebSocketDriftClientAccountSubscriber
|
|
|
206
299
|
}
|
|
207
300
|
|
|
208
301
|
async subscribeToOracle(oracleInfo: OracleInfo): Promise<boolean> {
|
|
302
|
+
const oracleString = oracleInfo.publicKey.toString();
|
|
209
303
|
const client = this.oracleClientCache.get(
|
|
210
304
|
oracleInfo.source,
|
|
211
305
|
this.program.provider.connection,
|
|
@@ -221,16 +315,13 @@ export class WebSocketDriftClientAccountSubscriber
|
|
|
221
315
|
this.resubOpts,
|
|
222
316
|
this.commitment
|
|
223
317
|
);
|
|
224
|
-
|
|
318
|
+
accountSubscriber.setData(this.initialOraclePriceData.get(oracleString));
|
|
225
319
|
await accountSubscriber.subscribe((data: OraclePriceData) => {
|
|
226
320
|
this.eventEmitter.emit('oraclePriceUpdate', oracleInfo.publicKey, data);
|
|
227
321
|
this.eventEmitter.emit('update');
|
|
228
322
|
});
|
|
229
323
|
|
|
230
|
-
this.oracleSubscribers.set(
|
|
231
|
-
oracleInfo.publicKey.toString(),
|
|
232
|
-
accountSubscriber
|
|
233
|
-
);
|
|
324
|
+
this.oracleSubscribers.set(oracleString, accountSubscriber);
|
|
234
325
|
return true;
|
|
235
326
|
}
|
|
236
327
|
|
package/src/addresses/pda.ts
CHANGED
|
@@ -87,6 +87,19 @@ export async function getPerpMarketPublicKey(
|
|
|
87
87
|
)[0];
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
+
export function getPerpMarketPublicKeySync(
|
|
91
|
+
programId: PublicKey,
|
|
92
|
+
marketIndex: number
|
|
93
|
+
): PublicKey {
|
|
94
|
+
return PublicKey.findProgramAddressSync(
|
|
95
|
+
[
|
|
96
|
+
Buffer.from(anchor.utils.bytes.utf8.encode('perp_market')),
|
|
97
|
+
new anchor.BN(marketIndex).toArrayLike(Buffer, 'le', 2),
|
|
98
|
+
],
|
|
99
|
+
programId
|
|
100
|
+
)[0];
|
|
101
|
+
}
|
|
102
|
+
|
|
90
103
|
export async function getSpotMarketPublicKey(
|
|
91
104
|
programId: PublicKey,
|
|
92
105
|
marketIndex: number
|
|
@@ -102,6 +115,19 @@ export async function getSpotMarketPublicKey(
|
|
|
102
115
|
)[0];
|
|
103
116
|
}
|
|
104
117
|
|
|
118
|
+
export function getSpotMarketPublicKeySync(
|
|
119
|
+
programId: PublicKey,
|
|
120
|
+
marketIndex: number
|
|
121
|
+
): PublicKey {
|
|
122
|
+
return PublicKey.findProgramAddressSync(
|
|
123
|
+
[
|
|
124
|
+
Buffer.from(anchor.utils.bytes.utf8.encode('spot_market')),
|
|
125
|
+
new anchor.BN(marketIndex).toArrayLike(Buffer, 'le', 2),
|
|
126
|
+
],
|
|
127
|
+
programId
|
|
128
|
+
)[0];
|
|
129
|
+
}
|
|
130
|
+
|
|
105
131
|
export async function getSpotMarketVaultPublicKey(
|
|
106
132
|
programId: PublicKey,
|
|
107
133
|
marketIndex: number
|
package/src/config.ts
CHANGED
|
@@ -132,8 +132,10 @@ export function getMarketsAndOraclesForSubscription(env: DriftEnv): {
|
|
|
132
132
|
|
|
133
133
|
export async function findAllMarketAndOracles(program: Program): Promise<{
|
|
134
134
|
perpMarketIndexes: number[];
|
|
135
|
+
perpMarketAccounts: PerpMarketAccount[];
|
|
135
136
|
spotMarketIndexes: number[];
|
|
136
137
|
oracleInfos: OracleInfo[];
|
|
138
|
+
spotMarketAccounts: SpotMarketAccount[];
|
|
137
139
|
}> {
|
|
138
140
|
const perpMarketIndexes = [];
|
|
139
141
|
const spotMarketIndexes = [];
|
|
@@ -164,7 +166,13 @@ export async function findAllMarketAndOracles(program: Program): Promise<{
|
|
|
164
166
|
|
|
165
167
|
return {
|
|
166
168
|
perpMarketIndexes,
|
|
169
|
+
perpMarketAccounts: perpMarketProgramAccounts.map(
|
|
170
|
+
(account) => account.account
|
|
171
|
+
),
|
|
167
172
|
spotMarketIndexes,
|
|
173
|
+
spotMarketAccounts: spotMarketProgramAccounts.map(
|
|
174
|
+
(account) => account.account
|
|
175
|
+
),
|
|
168
176
|
oracleInfos: Array.from(oracleInfos.values()),
|
|
169
177
|
};
|
|
170
178
|
}
|