@drift-labs/sdk 0.1.18-orders.0 → 0.1.18-orders.4
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 +133 -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 +9 -3
- package/lib/index.js +10 -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 +2 -1
- 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 +186 -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 +9 -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 +1 -1
- 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,186 @@
|
|
|
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
|
+
this.accountsToPoll.set(userOrdersPublicKey.toString(), {
|
|
93
|
+
key: 'userOrders',
|
|
94
|
+
publicKey: userOrdersPublicKey,
|
|
95
|
+
eventType: 'userOrdersData',
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
for (const [_, accountToPoll] of this.accountsToPoll) {
|
|
99
|
+
accountToPoll.callbackId = this.accountLoader.addAccount(
|
|
100
|
+
accountToPoll.publicKey,
|
|
101
|
+
(buffer) => {
|
|
102
|
+
const account = this.program.account[
|
|
103
|
+
accountToPoll.key
|
|
104
|
+
].coder.accounts.decode(capitalize(accountToPoll.key), buffer);
|
|
105
|
+
this[accountToPoll.key] = account;
|
|
106
|
+
// @ts-ignore
|
|
107
|
+
this.eventEmitter.emit(accountToPoll.eventType, account);
|
|
108
|
+
this.eventEmitter.emit('update');
|
|
109
|
+
}
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
this.errorCallbackId = this.accountLoader.addErrorCallbacks((error) => {
|
|
114
|
+
this.eventEmitter.emit('error', error);
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
async fetchIfUnloaded(): Promise<void> {
|
|
119
|
+
let shouldFetch = false;
|
|
120
|
+
for (const [_, accountToPoll] of this.accountsToPoll) {
|
|
121
|
+
if (this[accountToPoll.key] === undefined) {
|
|
122
|
+
shouldFetch = true;
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (shouldFetch) {
|
|
128
|
+
await this.fetch();
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
async fetch(): Promise<void> {
|
|
133
|
+
await this.accountLoader.load();
|
|
134
|
+
for (const [_, accountToPoll] of this.accountsToPoll) {
|
|
135
|
+
const buffer = this.accountLoader.getAccountData(accountToPoll.publicKey);
|
|
136
|
+
if (buffer) {
|
|
137
|
+
this[accountToPoll.key] = this.program.account[
|
|
138
|
+
accountToPoll.key
|
|
139
|
+
].coder.accounts.decode(capitalize(accountToPoll.key), buffer);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
async unsubscribe(): Promise<void> {
|
|
145
|
+
if (!this.isSubscribed) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
for (const [_, accountToPoll] of this.accountsToPoll) {
|
|
150
|
+
this.accountLoader.removeAccount(
|
|
151
|
+
accountToPoll.publicKey,
|
|
152
|
+
accountToPoll.callbackId
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
this.accountLoader.removeErrorCallbacks(this.errorCallbackId);
|
|
157
|
+
this.errorCallbackId = undefined;
|
|
158
|
+
|
|
159
|
+
this.accountsToPoll.clear();
|
|
160
|
+
|
|
161
|
+
this.isSubscribed = false;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
assertIsSubscribed(): void {
|
|
165
|
+
if (!this.isSubscribed) {
|
|
166
|
+
throw new NotSubscribedError(
|
|
167
|
+
'You must call `subscribe` before using this function'
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
public getUserAccount(): UserAccount {
|
|
173
|
+
this.assertIsSubscribed();
|
|
174
|
+
return this.user;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
public getUserPositionsAccount(): UserPositionsAccount {
|
|
178
|
+
this.assertIsSubscribed();
|
|
179
|
+
return this.userPositions;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
public getUserOrdersAccount(): UserOrdersAccount {
|
|
183
|
+
this.assertIsSubscribed();
|
|
184
|
+
return this.userOrders;
|
|
185
|
+
}
|
|
186
|
+
}
|
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
|
}
|
package/src/admin.ts
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
OracleSource,
|
|
13
13
|
OrderFillerRewardStructure,
|
|
14
14
|
} from './types';
|
|
15
|
-
import { BN,
|
|
15
|
+
import { BN, Provider } from '@project-serum/anchor';
|
|
16
16
|
import * as anchor from '@project-serum/anchor';
|
|
17
17
|
import {
|
|
18
18
|
getClearingHouseStateAccountPublicKey,
|
|
@@ -22,11 +22,12 @@ import {
|
|
|
22
22
|
import { TOKEN_PROGRAM_ID } from '@solana/spl-token';
|
|
23
23
|
import { ClearingHouse } from './clearingHouse';
|
|
24
24
|
import { PEG_PRECISION } from './constants/numericConstants';
|
|
25
|
-
import clearingHouseIDL from './idl/clearing_house.json';
|
|
26
|
-
import { DefaultClearingHouseAccountSubscriber } from './accounts/defaultClearingHouseAccountSubscriber';
|
|
27
|
-
import { DefaultTxSender } from './tx/defaultTxSender';
|
|
28
25
|
import { calculateTargetPriceTrade } from './math/trade';
|
|
29
26
|
import { calculateAmmReservesAfterSwap, getSwapDirection } from './math/amm';
|
|
27
|
+
import {
|
|
28
|
+
getAdmin,
|
|
29
|
+
getWebSocketClearingHouseConfig,
|
|
30
|
+
} from './factory/clearingHouse';
|
|
30
31
|
|
|
31
32
|
export class Admin extends ClearingHouse {
|
|
32
33
|
public static from(
|
|
@@ -35,24 +36,13 @@ export class Admin extends ClearingHouse {
|
|
|
35
36
|
clearingHouseProgramId: PublicKey,
|
|
36
37
|
opts: ConfirmOptions = Provider.defaultOptions()
|
|
37
38
|
): Admin {
|
|
38
|
-
const
|
|
39
|
-
const program = new Program(
|
|
40
|
-
clearingHouseIDL as Idl,
|
|
41
|
-
clearingHouseProgramId,
|
|
42
|
-
provider
|
|
43
|
-
);
|
|
44
|
-
const accountSubscriber = new DefaultClearingHouseAccountSubscriber(
|
|
45
|
-
program
|
|
46
|
-
);
|
|
47
|
-
const txSender = new DefaultTxSender(provider);
|
|
48
|
-
return new Admin(
|
|
39
|
+
const config = getWebSocketClearingHouseConfig(
|
|
49
40
|
connection,
|
|
50
41
|
wallet,
|
|
51
|
-
|
|
52
|
-
accountSubscriber,
|
|
53
|
-
txSender,
|
|
42
|
+
clearingHouseProgramId,
|
|
54
43
|
opts
|
|
55
44
|
);
|
|
45
|
+
return getAdmin(config);
|
|
56
46
|
}
|
|
57
47
|
|
|
58
48
|
public async initialize(
|
|
@@ -165,7 +155,7 @@ export class Admin extends ClearingHouse {
|
|
|
165
155
|
await this.program.account.depositHistory.createInstruction(
|
|
166
156
|
depositHistory
|
|
167
157
|
),
|
|
168
|
-
await this.program.account.
|
|
158
|
+
await this.program.account.extendedCurveHistory.createInstruction(
|
|
169
159
|
curveHistory
|
|
170
160
|
),
|
|
171
161
|
],
|
|
@@ -275,13 +265,38 @@ export class Admin extends ClearingHouse {
|
|
|
275
265
|
marketIndex: BN
|
|
276
266
|
): Promise<TransactionSignature> {
|
|
277
267
|
const state = this.getStateAccount();
|
|
268
|
+
const markets = this.getMarketsAccount();
|
|
269
|
+
const marketData = markets.markets[marketIndex.toNumber()];
|
|
270
|
+
const ammData = marketData.amm;
|
|
271
|
+
|
|
278
272
|
return await this.program.rpc.updateK(sqrtK, marketIndex, {
|
|
279
273
|
accounts: {
|
|
280
274
|
state: await this.getStatePublicKey(),
|
|
281
275
|
admin: this.wallet.publicKey,
|
|
282
276
|
markets: state.markets,
|
|
277
|
+
curveHistory: state.extendedCurveHistory,
|
|
278
|
+
oracle: ammData.oracle,
|
|
279
|
+
},
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
public async updateCurveHistory(): Promise<TransactionSignature> {
|
|
284
|
+
const extendedCurveHistory = anchor.web3.Keypair.generate();
|
|
285
|
+
|
|
286
|
+
const state = this.getStateAccount();
|
|
287
|
+
return await this.program.rpc.updateCurveHistory({
|
|
288
|
+
accounts: {
|
|
289
|
+
state: await this.getStatePublicKey(),
|
|
290
|
+
admin: this.wallet.publicKey,
|
|
283
291
|
curveHistory: state.curveHistory,
|
|
292
|
+
extendedCurveHistory: extendedCurveHistory.publicKey,
|
|
284
293
|
},
|
|
294
|
+
instructions: [
|
|
295
|
+
await this.program.account.extendedCurveHistory.createInstruction(
|
|
296
|
+
extendedCurveHistory
|
|
297
|
+
),
|
|
298
|
+
],
|
|
299
|
+
signers: [extendedCurveHistory],
|
|
285
300
|
});
|
|
286
301
|
}
|
|
287
302
|
|
|
@@ -334,7 +349,45 @@ export class Admin extends ClearingHouse {
|
|
|
334
349
|
admin: this.wallet.publicKey,
|
|
335
350
|
oracle: ammData.oracle,
|
|
336
351
|
markets: state.markets,
|
|
337
|
-
curveHistory: state.
|
|
352
|
+
curveHistory: state.extendedCurveHistory,
|
|
353
|
+
},
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
public async updateAmmOracleTwap(
|
|
358
|
+
marketIndex: BN
|
|
359
|
+
): Promise<TransactionSignature> {
|
|
360
|
+
const state = this.getStateAccount();
|
|
361
|
+
const markets = this.getMarketsAccount();
|
|
362
|
+
const marketData = markets.markets[marketIndex.toNumber()];
|
|
363
|
+
const ammData = marketData.amm;
|
|
364
|
+
|
|
365
|
+
return await this.program.rpc.updateAmmOracleTwap(marketIndex, {
|
|
366
|
+
accounts: {
|
|
367
|
+
state: await this.getStatePublicKey(),
|
|
368
|
+
admin: this.wallet.publicKey,
|
|
369
|
+
oracle: ammData.oracle,
|
|
370
|
+
markets: state.markets,
|
|
371
|
+
curveHistory: state.extendedCurveHistory,
|
|
372
|
+
},
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
public async resetAmmOracleTwap(
|
|
377
|
+
marketIndex: BN
|
|
378
|
+
): Promise<TransactionSignature> {
|
|
379
|
+
const state = this.getStateAccount();
|
|
380
|
+
const markets = this.getMarketsAccount();
|
|
381
|
+
const marketData = markets.markets[marketIndex.toNumber()];
|
|
382
|
+
const ammData = marketData.amm;
|
|
383
|
+
|
|
384
|
+
return await this.program.rpc.resetAmmOracleTwap(marketIndex, {
|
|
385
|
+
accounts: {
|
|
386
|
+
state: await this.getStatePublicKey(),
|
|
387
|
+
admin: this.wallet.publicKey,
|
|
388
|
+
oracle: ammData.oracle,
|
|
389
|
+
markets: state.markets,
|
|
390
|
+
curveHistory: state.extendedCurveHistory,
|
|
338
391
|
},
|
|
339
392
|
});
|
|
340
393
|
}
|