@drift-labs/sdk 0.1.18-orders.1 → 0.1.18-orders.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/lib/accounts/bulkAccountLoader.d.ts +31 -0
- package/lib/accounts/bulkAccountLoader.js +175 -0
- package/lib/accounts/bulkUserSubscription.d.ts +7 -0
- package/lib/accounts/bulkUserSubscription.js +28 -0
- package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +49 -0
- package/lib/accounts/pollingClearingHouseAccountSubscriber.js +228 -0
- package/lib/accounts/pollingTokenAccountSubscriber.d.ts +25 -0
- package/lib/accounts/pollingTokenAccountSubscriber.js +79 -0
- package/lib/accounts/pollingUserAccountSubscriber.d.ts +32 -0
- package/lib/accounts/pollingUserAccountSubscriber.js +136 -0
- package/lib/accounts/types.d.ts +34 -25
- package/lib/accounts/utils.d.ts +1 -0
- package/lib/accounts/utils.js +7 -0
- package/lib/accounts/webSocketAccountSubscriber.d.ts +6 -2
- package/lib/accounts/webSocketAccountSubscriber.js +43 -12
- package/lib/accounts/{defaultClearingHouseAccountSubscriber.d.ts → webSocketClearingHouseAccountSubscriber.d.ts} +6 -4
- package/lib/accounts/{defaultClearingHouseAccountSubscriber.js → webSocketClearingHouseAccountSubscriber.js} +5 -4
- package/lib/accounts/{defaultUserAccountSubscriber.d.ts → webSocketUserAccountSubscriber.d.ts} +3 -1
- package/lib/accounts/{defaultUserAccountSubscriber.js → webSocketUserAccountSubscriber.js} +10 -7
- package/lib/addresses.d.ts +2 -2
- package/lib/addresses.js +4 -4
- package/lib/admin.d.ts +3 -0
- package/lib/admin.js +61 -13
- package/lib/clearingHouse.d.ts +20 -4
- package/lib/clearingHouse.js +90 -10
- package/lib/clearingHouseUser.d.ts +12 -4
- package/lib/clearingHouseUser.js +35 -25
- package/lib/config.js +1 -1
- package/lib/constants/markets.d.ts +2 -1
- package/lib/constants/markets.js +35 -14
- package/lib/constants/numericConstants.d.ts +3 -1
- package/lib/constants/numericConstants.js +15 -17
- package/lib/examples/makeTradeExample.js +1 -1
- package/lib/factory/clearingHouse.d.ts +25 -0
- package/lib/factory/clearingHouse.js +64 -0
- package/lib/factory/clearingHouseUser.d.ts +19 -0
- package/lib/factory/clearingHouseUser.js +34 -0
- package/lib/idl/clearing_house.json +366 -17
- package/lib/index.d.ts +8 -3
- package/lib/index.js +9 -3
- package/lib/math/conversion.d.ts +1 -1
- package/lib/math/funding.js +4 -1
- package/lib/math/insuranceFund.d.ts +2 -1
- package/lib/math/insuranceFund.js +3 -6
- package/lib/math/position.d.ts +2 -1
- package/lib/math/position.js +2 -5
- package/lib/math/utils.d.ts +2 -1
- package/lib/math/utils.js +3 -3
- package/lib/mockUSDCFaucet.d.ts +2 -1
- package/lib/orderParams.d.ts +3 -3
- package/lib/orderParams.js +28 -8
- package/lib/orders.d.ts +3 -2
- package/lib/orders.js +8 -8
- package/lib/token/index.d.ts +3 -0
- package/lib/token/index.js +38 -0
- package/lib/types.d.ts +20 -8
- package/lib/types.js +2 -2
- package/package.json +11 -3
- package/src/accounts/bulkAccountLoader.ts +215 -0
- package/src/accounts/bulkUserSubscription.ts +28 -0
- package/src/accounts/pollingClearingHouseAccountSubscriber.ts +326 -0
- package/src/accounts/pollingTokenAccountSubscriber.ts +99 -0
- package/src/accounts/pollingUserAccountSubscriber.ts +194 -0
- package/src/accounts/types.ts +40 -30
- package/src/accounts/utils.ts +3 -0
- package/src/accounts/webSocketAccountSubscriber.ts +67 -17
- package/src/accounts/{defaultClearingHouseAccountSubscriber.ts → webSocketClearingHouseAccountSubscriber.ts} +9 -6
- package/src/accounts/{defaultUserAccountSubscriber.ts → webSocketUserAccountSubscriber.ts} +10 -5
- package/src/addresses.ts +6 -4
- package/src/admin.ts +73 -20
- package/src/clearingHouse.ts +125 -25
- package/src/clearingHouseUser.ts +28 -8
- package/src/config.ts +1 -1
- package/src/constants/markets.ts +25 -1
- package/src/constants/numericConstants.ts +2 -1
- package/src/examples/makeTradeExample.ts +4 -1
- package/src/factory/clearingHouse.ts +125 -0
- package/src/factory/clearingHouseUser.ts +73 -0
- package/src/idl/clearing_house.json +366 -17
- package/src/index.ts +8 -3
- package/src/math/conversion.ts +1 -1
- package/src/math/funding.ts +5 -1
- package/src/math/insuranceFund.ts +1 -1
- package/src/math/position.ts +1 -1
- package/src/math/utils.ts +1 -1
- package/src/mockUSDCFaucet.ts +1 -1
- package/src/orderParams.ts +30 -7
- package/src/orders.ts +13 -7
- package/src/token/index.ts +37 -0
- package/src/types.ts +17 -6
- package/lib/accounts/defaultHistoryAccountSubscriber.d.ts +0 -28
- package/lib/accounts/defaultHistoryAccountSubscriber.js +0 -110
- package/src/accounts/defaultHistoryAccountSubscriber.ts +0 -176
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AccountToPoll,
|
|
3
|
+
NotSubscribedError,
|
|
4
|
+
UserAccountEvents,
|
|
5
|
+
UserAccountSubscriber,
|
|
6
|
+
} from './types';
|
|
7
|
+
import { Program } from '@project-serum/anchor';
|
|
8
|
+
import StrictEventEmitter from 'strict-event-emitter-types';
|
|
9
|
+
import { EventEmitter } from 'events';
|
|
10
|
+
import { PublicKey } from '@solana/web3.js';
|
|
11
|
+
import {
|
|
12
|
+
getUserAccountPublicKey,
|
|
13
|
+
getUserOrdersAccountPublicKey,
|
|
14
|
+
} from '../addresses';
|
|
15
|
+
import { UserAccount, UserOrdersAccount, UserPositionsAccount } from '../types';
|
|
16
|
+
import { BulkAccountLoader } from './bulkAccountLoader';
|
|
17
|
+
import { capitalize } from './utils';
|
|
18
|
+
import { ClearingHouseConfigType } from '../factory/clearingHouse';
|
|
19
|
+
|
|
20
|
+
export class PollingUserAccountSubscriber implements UserAccountSubscriber {
|
|
21
|
+
isSubscribed: boolean;
|
|
22
|
+
program: Program;
|
|
23
|
+
eventEmitter: StrictEventEmitter<EventEmitter, UserAccountEvents>;
|
|
24
|
+
authority: PublicKey;
|
|
25
|
+
|
|
26
|
+
accountLoader: BulkAccountLoader;
|
|
27
|
+
accountsToPoll = new Map<string, AccountToPoll>();
|
|
28
|
+
errorCallbackId?: string;
|
|
29
|
+
|
|
30
|
+
user?: UserAccount;
|
|
31
|
+
userPositions?: UserPositionsAccount;
|
|
32
|
+
userOrders?: UserOrdersAccount;
|
|
33
|
+
|
|
34
|
+
type: ClearingHouseConfigType = 'polling';
|
|
35
|
+
|
|
36
|
+
public constructor(
|
|
37
|
+
program: Program,
|
|
38
|
+
authority: PublicKey,
|
|
39
|
+
accountLoader: BulkAccountLoader
|
|
40
|
+
) {
|
|
41
|
+
this.isSubscribed = false;
|
|
42
|
+
this.program = program;
|
|
43
|
+
this.authority = authority;
|
|
44
|
+
this.accountLoader = accountLoader;
|
|
45
|
+
this.eventEmitter = new EventEmitter();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async subscribe(): Promise<boolean> {
|
|
49
|
+
if (this.isSubscribed) {
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
await this.addToAccountLoader();
|
|
54
|
+
await this.fetchIfUnloaded();
|
|
55
|
+
this.eventEmitter.emit('update');
|
|
56
|
+
|
|
57
|
+
this.isSubscribed = true;
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async addToAccountLoader(): Promise<void> {
|
|
62
|
+
if (this.accountsToPoll.size > 0) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const userPublicKey = await getUserAccountPublicKey(
|
|
67
|
+
this.program.programId,
|
|
68
|
+
this.authority
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
const userAccount = (await this.program.account.user.fetch(
|
|
72
|
+
userPublicKey
|
|
73
|
+
)) as UserAccount;
|
|
74
|
+
|
|
75
|
+
this.accountsToPoll.set(userPublicKey.toString(), {
|
|
76
|
+
key: 'user',
|
|
77
|
+
publicKey: userPublicKey,
|
|
78
|
+
eventType: 'userAccountData',
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
this.accountsToPoll.set(userAccount.positions.toString(), {
|
|
82
|
+
key: 'userPositions',
|
|
83
|
+
publicKey: userAccount.positions,
|
|
84
|
+
eventType: 'userPositionsData',
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
const userOrdersPublicKey = await getUserOrdersAccountPublicKey(
|
|
88
|
+
this.program.programId,
|
|
89
|
+
userPublicKey
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
const userOrdersExist =
|
|
93
|
+
(
|
|
94
|
+
await this.program.provider.connection.getParsedAccountInfo(
|
|
95
|
+
userOrdersPublicKey
|
|
96
|
+
)
|
|
97
|
+
).value !== null;
|
|
98
|
+
if (userOrdersExist) {
|
|
99
|
+
this.accountsToPoll.set(userOrdersPublicKey.toString(), {
|
|
100
|
+
key: 'userOrders',
|
|
101
|
+
publicKey: userOrdersPublicKey,
|
|
102
|
+
eventType: 'userOrdersData',
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
for (const [_, accountToPoll] of this.accountsToPoll) {
|
|
107
|
+
accountToPoll.callbackId = this.accountLoader.addAccount(
|
|
108
|
+
accountToPoll.publicKey,
|
|
109
|
+
(buffer) => {
|
|
110
|
+
const account = this.program.account[
|
|
111
|
+
accountToPoll.key
|
|
112
|
+
].coder.accounts.decode(capitalize(accountToPoll.key), buffer);
|
|
113
|
+
this[accountToPoll.key] = account;
|
|
114
|
+
// @ts-ignore
|
|
115
|
+
this.eventEmitter.emit(accountToPoll.eventType, account);
|
|
116
|
+
this.eventEmitter.emit('update');
|
|
117
|
+
}
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
this.errorCallbackId = this.accountLoader.addErrorCallbacks((error) => {
|
|
122
|
+
this.eventEmitter.emit('error', error);
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async fetchIfUnloaded(): Promise<void> {
|
|
127
|
+
let shouldFetch = false;
|
|
128
|
+
for (const [_, accountToPoll] of this.accountsToPoll) {
|
|
129
|
+
if (this[accountToPoll.key] === undefined) {
|
|
130
|
+
shouldFetch = true;
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (shouldFetch) {
|
|
136
|
+
await this.fetch();
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
async fetch(): Promise<void> {
|
|
141
|
+
await this.accountLoader.load();
|
|
142
|
+
for (const [_, accountToPoll] of this.accountsToPoll) {
|
|
143
|
+
const buffer = this.accountLoader.getAccountData(accountToPoll.publicKey);
|
|
144
|
+
if (buffer) {
|
|
145
|
+
this[accountToPoll.key] = this.program.account[
|
|
146
|
+
accountToPoll.key
|
|
147
|
+
].coder.accounts.decode(capitalize(accountToPoll.key), buffer);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
async unsubscribe(): Promise<void> {
|
|
153
|
+
if (!this.isSubscribed) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
for (const [_, accountToPoll] of this.accountsToPoll) {
|
|
158
|
+
this.accountLoader.removeAccount(
|
|
159
|
+
accountToPoll.publicKey,
|
|
160
|
+
accountToPoll.callbackId
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
this.accountLoader.removeErrorCallbacks(this.errorCallbackId);
|
|
165
|
+
this.errorCallbackId = undefined;
|
|
166
|
+
|
|
167
|
+
this.accountsToPoll.clear();
|
|
168
|
+
|
|
169
|
+
this.isSubscribed = false;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
assertIsSubscribed(): void {
|
|
173
|
+
if (!this.isSubscribed) {
|
|
174
|
+
throw new NotSubscribedError(
|
|
175
|
+
'You must call `subscribe` before using this function'
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
public getUserAccount(): UserAccount {
|
|
181
|
+
this.assertIsSubscribed();
|
|
182
|
+
return this.user;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
public getUserPositionsAccount(): UserPositionsAccount {
|
|
186
|
+
this.assertIsSubscribed();
|
|
187
|
+
return this.userPositions;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
public getUserOrdersAccount(): UserOrdersAccount {
|
|
191
|
+
this.assertIsSubscribed();
|
|
192
|
+
return this.userOrders;
|
|
193
|
+
}
|
|
194
|
+
}
|
package/src/accounts/types.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
|
-
CurveHistoryAccount,
|
|
3
2
|
DepositHistoryAccount,
|
|
3
|
+
ExtendedCurveHistoryAccount,
|
|
4
4
|
FundingPaymentHistoryAccount,
|
|
5
5
|
FundingRateHistoryAccount,
|
|
6
6
|
LiquidationHistoryAccount,
|
|
@@ -15,12 +15,15 @@ import {
|
|
|
15
15
|
} from '../types';
|
|
16
16
|
import StrictEventEmitter from 'strict-event-emitter-types';
|
|
17
17
|
import { EventEmitter } from 'events';
|
|
18
|
+
import { PublicKey } from '@solana/web3.js';
|
|
19
|
+
import { AccountInfo } from '@solana/spl-token';
|
|
20
|
+
import { ClearingHouseConfigType, ClearingHouseUserConfigType } from '..';
|
|
18
21
|
|
|
19
22
|
export interface AccountSubscriber<T> {
|
|
20
23
|
data?: T;
|
|
21
24
|
subscribe(onChange: (data: T) => void): Promise<void>;
|
|
22
25
|
fetch(): Promise<void>;
|
|
23
|
-
unsubscribe(): void
|
|
26
|
+
unsubscribe(): Promise<void>;
|
|
24
27
|
}
|
|
25
28
|
|
|
26
29
|
export class NotSubscribedError extends Error {
|
|
@@ -37,10 +40,11 @@ export interface ClearingHouseAccountEvents {
|
|
|
37
40
|
tradeHistoryAccountUpdate: (payload: TradeHistoryAccount) => void;
|
|
38
41
|
liquidationHistoryAccountUpdate: (payload: LiquidationHistoryAccount) => void;
|
|
39
42
|
depositHistoryAccountUpdate: (payload: DepositHistoryAccount) => void;
|
|
40
|
-
curveHistoryAccountUpdate: (payload:
|
|
43
|
+
curveHistoryAccountUpdate: (payload: ExtendedCurveHistoryAccount) => void;
|
|
41
44
|
orderHistoryAccountUpdate: (payload: OrderHistoryAccount) => void;
|
|
42
45
|
orderStateAccountUpdate: (payload: OrderStateAccount) => void;
|
|
43
46
|
update: void;
|
|
47
|
+
error: (e: Error) => void;
|
|
44
48
|
}
|
|
45
49
|
|
|
46
50
|
export type ClearingHouseAccountTypes =
|
|
@@ -70,37 +74,12 @@ export interface ClearingHouseAccountSubscriber {
|
|
|
70
74
|
getDepositHistoryAccount(): DepositHistoryAccount;
|
|
71
75
|
getFundingPaymentHistoryAccount(): FundingPaymentHistoryAccount;
|
|
72
76
|
getFundingRateHistoryAccount(): FundingRateHistoryAccount;
|
|
73
|
-
getCurveHistoryAccount():
|
|
77
|
+
getCurveHistoryAccount(): ExtendedCurveHistoryAccount;
|
|
74
78
|
getLiquidationHistoryAccount(): LiquidationHistoryAccount;
|
|
75
79
|
getOrderStateAccount(): OrderStateAccount;
|
|
76
80
|
getOrderHistoryAccount(): OrderHistoryAccount;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export interface HistoryAccountEvents {
|
|
80
|
-
fundingPaymentHistoryAccountUpdate: (
|
|
81
|
-
payload: FundingPaymentHistoryAccount
|
|
82
|
-
) => void;
|
|
83
|
-
fundingRateHistoryAccountUpdate: (payload: FundingRateHistoryAccount) => void;
|
|
84
|
-
tradeHistoryAccountUpdate: (payload: TradeHistoryAccount) => void;
|
|
85
|
-
liquidationHistoryAccountUpdate: (payload: LiquidationHistoryAccount) => void;
|
|
86
|
-
depositHistoryAccountUpdate: (payload: DepositHistoryAccount) => void;
|
|
87
|
-
curveHistoryAccountUpdate: (payload: CurveHistoryAccount) => void;
|
|
88
|
-
update: void;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export interface HistoryAccountSubscriber {
|
|
92
|
-
eventEmitter: StrictEventEmitter<EventEmitter, HistoryAccountEvents>;
|
|
93
|
-
isSubscribed: boolean;
|
|
94
|
-
|
|
95
|
-
subscribe(): Promise<boolean>;
|
|
96
|
-
unsubscribe(): Promise<void>;
|
|
97
81
|
|
|
98
|
-
|
|
99
|
-
getDepositHistoryAccount(): DepositHistoryAccount;
|
|
100
|
-
getFundingPaymentHistoryAccount(): FundingPaymentHistoryAccount;
|
|
101
|
-
getFundingRateHistoryAccount(): FundingRateHistoryAccount;
|
|
102
|
-
getCurveHistoryAccount(): CurveHistoryAccount;
|
|
103
|
-
getLiquidationHistoryAccount(): LiquidationHistoryAccount;
|
|
82
|
+
type: ClearingHouseConfigType;
|
|
104
83
|
}
|
|
105
84
|
|
|
106
85
|
export interface UserAccountEvents {
|
|
@@ -108,6 +87,7 @@ export interface UserAccountEvents {
|
|
|
108
87
|
userPositionsData: (payload: UserPositionsAccount) => void;
|
|
109
88
|
userOrdersData: (payload: UserOrdersAccount) => void;
|
|
110
89
|
update: void;
|
|
90
|
+
error: (e: Error) => void;
|
|
111
91
|
}
|
|
112
92
|
|
|
113
93
|
export interface UserAccountSubscriber {
|
|
@@ -121,4 +101,34 @@ export interface UserAccountSubscriber {
|
|
|
121
101
|
getUserAccount(): UserAccount;
|
|
122
102
|
getUserPositionsAccount(): UserPositionsAccount;
|
|
123
103
|
getUserOrdersAccount(): UserOrdersAccount;
|
|
104
|
+
type: ClearingHouseUserConfigType;
|
|
124
105
|
}
|
|
106
|
+
|
|
107
|
+
export interface TokenAccountEvents {
|
|
108
|
+
tokenAccountUpdate: (payload: AccountInfo) => void;
|
|
109
|
+
update: void;
|
|
110
|
+
error: (e: Error) => void;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export interface TokenAccountSubscriber {
|
|
114
|
+
eventEmitter: StrictEventEmitter<EventEmitter, TokenAccountEvents>;
|
|
115
|
+
isSubscribed: boolean;
|
|
116
|
+
|
|
117
|
+
subscribe(): Promise<boolean>;
|
|
118
|
+
fetch(): Promise<void>;
|
|
119
|
+
unsubscribe(): Promise<void>;
|
|
120
|
+
|
|
121
|
+
getTokenAccount(): AccountInfo;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export type AccountToPoll = {
|
|
125
|
+
key: string;
|
|
126
|
+
publicKey: PublicKey;
|
|
127
|
+
eventType: string;
|
|
128
|
+
callbackId?: string;
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
export type AccountData = {
|
|
132
|
+
slot: number;
|
|
133
|
+
buffer: Buffer | undefined;
|
|
134
|
+
};
|
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
import { AccountSubscriber } from './types';
|
|
1
|
+
import { AccountData, AccountSubscriber } from './types';
|
|
2
2
|
import { Program } from '@project-serum/anchor';
|
|
3
|
-
import { PublicKey } from '@solana/web3.js';
|
|
3
|
+
import { AccountInfo, Context, PublicKey } from '@solana/web3.js';
|
|
4
|
+
import { capitalize } from './utils';
|
|
5
|
+
import * as Buffer from 'buffer';
|
|
4
6
|
|
|
5
7
|
export class WebSocketAccountSubscriber<T> implements AccountSubscriber<T> {
|
|
6
8
|
data?: T;
|
|
9
|
+
accountData?: AccountData;
|
|
7
10
|
accountName: string;
|
|
8
11
|
program: Program;
|
|
9
12
|
accountPublicKey: PublicKey;
|
|
10
13
|
onChange: (data: T) => void;
|
|
14
|
+
listenerId?: number;
|
|
11
15
|
|
|
12
16
|
public constructor(
|
|
13
17
|
accountName: string,
|
|
@@ -20,32 +24,78 @@ export class WebSocketAccountSubscriber<T> implements AccountSubscriber<T> {
|
|
|
20
24
|
}
|
|
21
25
|
|
|
22
26
|
async subscribe(onChange: (data: T) => void): Promise<void> {
|
|
27
|
+
if (this.listenerId) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
23
31
|
this.onChange = onChange;
|
|
24
32
|
await this.fetch();
|
|
25
33
|
|
|
26
|
-
this.program.
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
this.
|
|
30
|
-
|
|
31
|
-
|
|
34
|
+
this.listenerId = this.program.provider.connection.onAccountChange(
|
|
35
|
+
this.accountPublicKey,
|
|
36
|
+
(accountInfo, context) => {
|
|
37
|
+
this.handleRpcResponse(context, accountInfo);
|
|
38
|
+
},
|
|
39
|
+
this.program.provider.opts.commitment
|
|
40
|
+
);
|
|
32
41
|
}
|
|
33
42
|
|
|
34
43
|
async fetch(): Promise<void> {
|
|
35
|
-
const
|
|
36
|
-
this.
|
|
37
|
-
|
|
44
|
+
const rpcResponse =
|
|
45
|
+
await this.program.provider.connection.getAccountInfoAndContext(
|
|
46
|
+
this.accountPublicKey,
|
|
47
|
+
this.program.provider.opts.commitment
|
|
48
|
+
);
|
|
49
|
+
this.handleRpcResponse(rpcResponse.context, rpcResponse?.value);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
handleRpcResponse(context: Context, accountInfo?: AccountInfo<Buffer>): void {
|
|
53
|
+
const newSlot = context.slot;
|
|
54
|
+
let newBuffer: Buffer | undefined = undefined;
|
|
55
|
+
if (accountInfo) {
|
|
56
|
+
newBuffer = accountInfo.data;
|
|
57
|
+
}
|
|
38
58
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
59
|
+
if (!this.accountData) {
|
|
60
|
+
this.accountData = {
|
|
61
|
+
buffer: newBuffer,
|
|
62
|
+
slot: newSlot,
|
|
63
|
+
};
|
|
64
|
+
if (newBuffer) {
|
|
65
|
+
this.data = this.program.account[
|
|
66
|
+
this.accountName
|
|
67
|
+
].coder.accounts.decode(capitalize(this.accountName), newBuffer);
|
|
68
|
+
this.onChange(this.data);
|
|
69
|
+
}
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (newSlot <= this.accountData.slot) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const oldBuffer = this.accountData.buffer;
|
|
78
|
+
if (newBuffer && (!oldBuffer || !newBuffer.equals(oldBuffer))) {
|
|
79
|
+
this.accountData = {
|
|
80
|
+
buffer: newBuffer,
|
|
81
|
+
slot: newSlot,
|
|
82
|
+
};
|
|
83
|
+
this.data = this.program.account[this.accountName].coder.accounts.decode(
|
|
84
|
+
capitalize(this.accountName),
|
|
85
|
+
newBuffer
|
|
86
|
+
);
|
|
42
87
|
this.onChange(this.data);
|
|
43
88
|
}
|
|
44
89
|
}
|
|
45
90
|
|
|
46
91
|
unsubscribe(): Promise<void> {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
92
|
+
if (this.listenerId) {
|
|
93
|
+
const promise =
|
|
94
|
+
this.program.provider.connection.removeAccountChangeListener(
|
|
95
|
+
this.listenerId
|
|
96
|
+
);
|
|
97
|
+
this.listenerId = undefined;
|
|
98
|
+
return promise;
|
|
99
|
+
}
|
|
50
100
|
}
|
|
51
101
|
}
|
|
@@ -5,8 +5,8 @@ import {
|
|
|
5
5
|
} from './types';
|
|
6
6
|
import { AccountSubscriber, NotSubscribedError } from './types';
|
|
7
7
|
import {
|
|
8
|
-
CurveHistoryAccount,
|
|
9
8
|
DepositHistoryAccount,
|
|
9
|
+
ExtendedCurveHistoryAccount,
|
|
10
10
|
FundingPaymentHistoryAccount,
|
|
11
11
|
FundingRateHistoryAccount,
|
|
12
12
|
LiquidationHistoryAccount,
|
|
@@ -21,8 +21,9 @@ import StrictEventEmitter from 'strict-event-emitter-types';
|
|
|
21
21
|
import { EventEmitter } from 'events';
|
|
22
22
|
import { getClearingHouseStateAccountPublicKey } from '../addresses';
|
|
23
23
|
import { WebSocketAccountSubscriber } from './webSocketAccountSubscriber';
|
|
24
|
+
import { ClearingHouseConfigType } from '../factory/clearingHouse';
|
|
24
25
|
|
|
25
|
-
export class
|
|
26
|
+
export class WebSocketClearingHouseAccountSubscriber
|
|
26
27
|
implements ClearingHouseAccountSubscriber
|
|
27
28
|
{
|
|
28
29
|
isSubscribed: boolean;
|
|
@@ -34,13 +35,15 @@ export class DefaultClearingHouseAccountSubscriber
|
|
|
34
35
|
depositHistoryAccountSubscriber?: AccountSubscriber<DepositHistoryAccount>;
|
|
35
36
|
fundingPaymentHistoryAccountSubscriber?: AccountSubscriber<FundingPaymentHistoryAccount>;
|
|
36
37
|
fundingRateHistoryAccountSubscriber?: AccountSubscriber<FundingRateHistoryAccount>;
|
|
37
|
-
curveHistoryAccountSubscriber?: AccountSubscriber<
|
|
38
|
+
curveHistoryAccountSubscriber?: AccountSubscriber<ExtendedCurveHistoryAccount>;
|
|
38
39
|
liquidationHistoryAccountSubscriber?: AccountSubscriber<LiquidationHistoryAccount>;
|
|
39
40
|
orderStateAccountSubscriber?: AccountSubscriber<OrderStateAccount>;
|
|
40
41
|
orderHistoryAccountSubscriber?: AccountSubscriber<OrderHistoryAccount>;
|
|
41
42
|
|
|
42
43
|
optionalExtraSubscriptions: ClearingHouseAccountTypes[] = [];
|
|
43
44
|
|
|
45
|
+
type: ClearingHouseConfigType = 'websocket';
|
|
46
|
+
|
|
44
47
|
private isSubscribing = false;
|
|
45
48
|
private subscriptionPromise: Promise<boolean>;
|
|
46
49
|
private subscriptionPromiseResolver: (val: boolean) => void;
|
|
@@ -145,9 +148,9 @@ export class DefaultClearingHouseAccountSubscriber
|
|
|
145
148
|
);
|
|
146
149
|
|
|
147
150
|
this.curveHistoryAccountSubscriber = new WebSocketAccountSubscriber(
|
|
148
|
-
'
|
|
151
|
+
'extendedCurveHistory',
|
|
149
152
|
this.program,
|
|
150
|
-
state.
|
|
153
|
+
state.extendedCurveHistory
|
|
151
154
|
);
|
|
152
155
|
|
|
153
156
|
this.orderHistoryAccountSubscriber = new WebSocketAccountSubscriber(
|
|
@@ -343,7 +346,7 @@ export class DefaultClearingHouseAccountSubscriber
|
|
|
343
346
|
return this.fundingRateHistoryAccountSubscriber.data;
|
|
344
347
|
}
|
|
345
348
|
|
|
346
|
-
public getCurveHistoryAccount():
|
|
349
|
+
public getCurveHistoryAccount(): ExtendedCurveHistoryAccount {
|
|
347
350
|
this.assertIsSubscribed();
|
|
348
351
|
this.assertOptionalIsSubscribed('curveHistoryAccount');
|
|
349
352
|
return this.curveHistoryAccountSubscriber.data;
|
|
@@ -14,8 +14,9 @@ import {
|
|
|
14
14
|
} from '../addresses';
|
|
15
15
|
import { WebSocketAccountSubscriber } from './webSocketAccountSubscriber';
|
|
16
16
|
import { UserAccount, UserOrdersAccount, UserPositionsAccount } from '../types';
|
|
17
|
+
import { ClearingHouseConfigType } from '../factory/clearingHouse';
|
|
17
18
|
|
|
18
|
-
export class
|
|
19
|
+
export class WebSocketUserAccountSubscriber implements UserAccountSubscriber {
|
|
19
20
|
isSubscribed: boolean;
|
|
20
21
|
program: Program;
|
|
21
22
|
eventEmitter: StrictEventEmitter<EventEmitter, UserAccountEvents>;
|
|
@@ -25,6 +26,8 @@ export class DefaultUserAccountSubscriber implements UserAccountSubscriber {
|
|
|
25
26
|
userPositionsAccountSubscriber: AccountSubscriber<UserPositionsAccount>;
|
|
26
27
|
userOrdersAccountSubscriber: AccountSubscriber<UserOrdersAccount>;
|
|
27
28
|
|
|
29
|
+
type: ClearingHouseConfigType = 'websocket';
|
|
30
|
+
|
|
28
31
|
public constructor(program: Program, authority: PublicKey) {
|
|
29
32
|
this.isSubscribed = false;
|
|
30
33
|
this.program = program;
|
|
@@ -67,7 +70,7 @@ export class DefaultUserAccountSubscriber implements UserAccountSubscriber {
|
|
|
67
70
|
|
|
68
71
|
const userOrdersPublicKey = await getUserOrdersAccountPublicKey(
|
|
69
72
|
this.program.programId,
|
|
70
|
-
|
|
73
|
+
userPublicKey
|
|
71
74
|
);
|
|
72
75
|
|
|
73
76
|
this.userOrdersAccountSubscriber = new WebSocketAccountSubscriber(
|
|
@@ -100,9 +103,11 @@ export class DefaultUserAccountSubscriber implements UserAccountSubscriber {
|
|
|
100
103
|
return;
|
|
101
104
|
}
|
|
102
105
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
+
await Promise.all([
|
|
107
|
+
this.userDataAccountSubscriber.unsubscribe(),
|
|
108
|
+
this.userPositionsAccountSubscriber.unsubscribe(),
|
|
109
|
+
await this.userOrdersAccountSubscriber.unsubscribe(),
|
|
110
|
+
]);
|
|
106
111
|
|
|
107
112
|
this.isSubscribed = false;
|
|
108
113
|
}
|
package/src/addresses.ts
CHANGED
|
@@ -50,12 +50,12 @@ export async function getUserAccountPublicKey(
|
|
|
50
50
|
|
|
51
51
|
export async function getUserOrdersAccountPublicKeyAndNonce(
|
|
52
52
|
programId: PublicKey,
|
|
53
|
-
|
|
53
|
+
userAccount: PublicKey
|
|
54
54
|
): Promise<[PublicKey, number]> {
|
|
55
55
|
return anchor.web3.PublicKey.findProgramAddress(
|
|
56
56
|
[
|
|
57
57
|
Buffer.from(anchor.utils.bytes.utf8.encode('user_orders')),
|
|
58
|
-
|
|
58
|
+
userAccount.toBuffer(),
|
|
59
59
|
],
|
|
60
60
|
programId
|
|
61
61
|
);
|
|
@@ -63,7 +63,9 @@ export async function getUserOrdersAccountPublicKeyAndNonce(
|
|
|
63
63
|
|
|
64
64
|
export async function getUserOrdersAccountPublicKey(
|
|
65
65
|
programId: PublicKey,
|
|
66
|
-
|
|
66
|
+
userAccount: PublicKey
|
|
67
67
|
): Promise<PublicKey> {
|
|
68
|
-
return (
|
|
68
|
+
return (
|
|
69
|
+
await getUserOrdersAccountPublicKeyAndNonce(programId, userAccount)
|
|
70
|
+
)[0];
|
|
69
71
|
}
|