@drift-labs/sdk 2.40.0-beta.1 → 2.40.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -1
- package/VERSION +1 -1
- package/bun.lockb +0 -0
- package/lib/accounts/types.d.ts +5 -1
- package/lib/accounts/webSocketAccountSubscriber.d.ts +6 -1
- package/lib/accounts/webSocketAccountSubscriber.js +28 -2
- package/lib/accounts/webSocketDriftClientAccountSubscriber.d.ts +2 -1
- package/lib/accounts/webSocketDriftClientAccountSubscriber.js +6 -5
- package/lib/accounts/webSocketProgramAccountSubscriber.d.ts +32 -0
- package/lib/accounts/webSocketProgramAccountSubscriber.js +99 -0
- package/lib/accounts/webSocketUserAccountSubscriber.d.ts +2 -1
- package/lib/accounts/webSocketUserAccountSubscriber.js +3 -2
- package/lib/accounts/webSocketUserStatsAccountSubsriber.d.ts +2 -1
- package/lib/accounts/webSocketUserStatsAccountSubsriber.js +3 -2
- package/lib/auctionSubscriber/auctionSubscriber.d.ts +3 -2
- package/lib/auctionSubscriber/auctionSubscriber.js +15 -7
- package/lib/auctionSubscriber/types.d.ts +1 -0
- package/lib/driftClient.d.ts +2 -1
- package/lib/driftClient.js +5 -4
- package/lib/driftClientConfig.d.ts +1 -0
- package/lib/idl/drift.json +51 -0
- package/lib/jupiter/jupiterClient.d.ts +3 -1
- package/lib/jupiter/jupiterClient.js +3 -1
- package/lib/math/amm.js +7 -2
- package/lib/math/superStake.d.ts +51 -4
- package/lib/math/superStake.js +173 -21
- package/lib/math/utils.d.ts +1 -0
- package/lib/math/utils.js +10 -1
- package/lib/orderSubscriber/OrderSubscriber.d.ts +1 -3
- package/lib/orderSubscriber/OrderSubscriber.js +4 -3
- package/lib/orderSubscriber/WebsocketSubscription.d.ts +4 -2
- package/lib/orderSubscriber/WebsocketSubscription.js +13 -12
- package/lib/orderSubscriber/types.d.ts +1 -0
- package/lib/user.d.ts +2 -2
- package/lib/user.js +5 -5
- package/package.json +1 -1
- package/src/accounts/types.ts +8 -1
- package/src/accounts/webSocketAccountSubscriber.ts +36 -2
- package/src/accounts/webSocketDriftClientAccountSubscriber.ts +15 -5
- package/src/accounts/webSocketProgramAccountSubscriber.ts +152 -0
- package/src/accounts/webSocketUserAccountSubscriber.ts +10 -2
- package/src/accounts/webSocketUserStatsAccountSubsriber.ts +10 -2
- package/src/auctionSubscriber/auctionSubscriber.ts +30 -21
- package/src/auctionSubscriber/types.ts +1 -0
- package/src/driftClient.ts +5 -1
- package/src/driftClientConfig.ts +1 -0
- package/src/idl/drift.json +51 -0
- package/src/jupiter/jupiterClient.ts +3 -0
- package/src/math/amm.ts +9 -2
- package/src/math/superStake.ts +248 -24
- package/src/math/utils.ts +12 -0
- package/src/orderSubscriber/OrderSubscriber.ts +12 -7
- package/src/orderSubscriber/WebsocketSubscription.ts +33 -23
- package/src/orderSubscriber/types.ts +1 -0
- package/src/user.ts +7 -5
|
@@ -31,6 +31,7 @@ export class WebSocketDriftClientAccountSubscriber
|
|
|
31
31
|
oracleInfos: OracleInfo[];
|
|
32
32
|
oracleClientCache = new OracleClientCache();
|
|
33
33
|
|
|
34
|
+
resubTimeoutMs?: number;
|
|
34
35
|
shouldFindAllMarketsAndOracles: boolean;
|
|
35
36
|
|
|
36
37
|
eventEmitter: StrictEventEmitter<EventEmitter, DriftClientAccountEvents>;
|
|
@@ -54,7 +55,8 @@ export class WebSocketDriftClientAccountSubscriber
|
|
|
54
55
|
perpMarketIndexes: number[],
|
|
55
56
|
spotMarketIndexes: number[],
|
|
56
57
|
oracleInfos: OracleInfo[],
|
|
57
|
-
shouldFindAllMarketsAndOracles: boolean
|
|
58
|
+
shouldFindAllMarketsAndOracles: boolean,
|
|
59
|
+
resubTimeoutMs?: number
|
|
58
60
|
) {
|
|
59
61
|
this.isSubscribed = false;
|
|
60
62
|
this.program = program;
|
|
@@ -63,6 +65,7 @@ export class WebSocketDriftClientAccountSubscriber
|
|
|
63
65
|
this.spotMarketIndexes = spotMarketIndexes;
|
|
64
66
|
this.oracleInfos = oracleInfos;
|
|
65
67
|
this.shouldFindAllMarketsAndOracles = shouldFindAllMarketsAndOracles;
|
|
68
|
+
this.resubTimeoutMs = resubTimeoutMs;
|
|
66
69
|
}
|
|
67
70
|
|
|
68
71
|
public async subscribe(): Promise<boolean> {
|
|
@@ -96,7 +99,9 @@ export class WebSocketDriftClientAccountSubscriber
|
|
|
96
99
|
this.stateAccountSubscriber = new WebSocketAccountSubscriber(
|
|
97
100
|
'state',
|
|
98
101
|
this.program,
|
|
99
|
-
statePublicKey
|
|
102
|
+
statePublicKey,
|
|
103
|
+
undefined,
|
|
104
|
+
this.resubTimeoutMs
|
|
100
105
|
);
|
|
101
106
|
await this.stateAccountSubscriber.subscribe((data: StateAccount) => {
|
|
102
107
|
this.eventEmitter.emit('stateAccountUpdate', data);
|
|
@@ -136,7 +141,9 @@ export class WebSocketDriftClientAccountSubscriber
|
|
|
136
141
|
const accountSubscriber = new WebSocketAccountSubscriber<PerpMarketAccount>(
|
|
137
142
|
'perpMarket',
|
|
138
143
|
this.program,
|
|
139
|
-
perpMarketPublicKey
|
|
144
|
+
perpMarketPublicKey,
|
|
145
|
+
undefined,
|
|
146
|
+
this.resubTimeoutMs
|
|
140
147
|
);
|
|
141
148
|
await accountSubscriber.subscribe((data: PerpMarketAccount) => {
|
|
142
149
|
this.eventEmitter.emit('perpMarketAccountUpdate', data);
|
|
@@ -161,7 +168,9 @@ export class WebSocketDriftClientAccountSubscriber
|
|
|
161
168
|
const accountSubscriber = new WebSocketAccountSubscriber<SpotMarketAccount>(
|
|
162
169
|
'spotMarket',
|
|
163
170
|
this.program,
|
|
164
|
-
marketPublicKey
|
|
171
|
+
marketPublicKey,
|
|
172
|
+
undefined,
|
|
173
|
+
this.resubTimeoutMs
|
|
165
174
|
);
|
|
166
175
|
await accountSubscriber.subscribe((data: SpotMarketAccount) => {
|
|
167
176
|
this.eventEmitter.emit('spotMarketAccountUpdate', data);
|
|
@@ -192,7 +201,8 @@ export class WebSocketDriftClientAccountSubscriber
|
|
|
192
201
|
oracleInfo.publicKey,
|
|
193
202
|
(buffer: Buffer) => {
|
|
194
203
|
return client.getOraclePriceDataFromBuffer(buffer);
|
|
195
|
-
}
|
|
204
|
+
},
|
|
205
|
+
this.resubTimeoutMs
|
|
196
206
|
);
|
|
197
207
|
|
|
198
208
|
await accountSubscriber.subscribe((data: OraclePriceData) => {
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { DataAndSlot, BufferAndSlot, ProgramAccountSubscriber } from './types';
|
|
2
|
+
import { AnchorProvider, Program } from '@coral-xyz/anchor';
|
|
3
|
+
import {
|
|
4
|
+
Commitment,
|
|
5
|
+
Context,
|
|
6
|
+
KeyedAccountInfo,
|
|
7
|
+
MemcmpFilter,
|
|
8
|
+
PublicKey,
|
|
9
|
+
} from '@solana/web3.js';
|
|
10
|
+
import * as Buffer from 'buffer';
|
|
11
|
+
|
|
12
|
+
export class WebSocketProgramAccountSubscriber<T>
|
|
13
|
+
implements ProgramAccountSubscriber<T>
|
|
14
|
+
{
|
|
15
|
+
subscriptionName: string;
|
|
16
|
+
accountDiscriminator: string;
|
|
17
|
+
dataAndSlot?: DataAndSlot<T> & { accountId: PublicKey };
|
|
18
|
+
bufferAndSlot?: BufferAndSlot;
|
|
19
|
+
program: Program;
|
|
20
|
+
decodeBuffer: (accountName: string, ix: Buffer) => T;
|
|
21
|
+
onChange: (accountId: PublicKey, data: T, context: Context) => void;
|
|
22
|
+
listenerId?: number;
|
|
23
|
+
resubTimeoutMs?: number;
|
|
24
|
+
timeoutId?: NodeJS.Timeout;
|
|
25
|
+
options: { filters: MemcmpFilter[]; commitment?: Commitment };
|
|
26
|
+
|
|
27
|
+
receivingData = false;
|
|
28
|
+
|
|
29
|
+
public constructor(
|
|
30
|
+
subscriptionName: string,
|
|
31
|
+
accountDiscriminator: string,
|
|
32
|
+
program: Program,
|
|
33
|
+
decodeBufferFn: (accountName: string, ix: Buffer) => T,
|
|
34
|
+
options: { filters: MemcmpFilter[]; commitment?: Commitment } = {
|
|
35
|
+
filters: [],
|
|
36
|
+
},
|
|
37
|
+
resubTimeoutMs?: number
|
|
38
|
+
) {
|
|
39
|
+
this.subscriptionName = subscriptionName;
|
|
40
|
+
this.accountDiscriminator = accountDiscriminator;
|
|
41
|
+
this.program = program;
|
|
42
|
+
this.decodeBuffer = decodeBufferFn;
|
|
43
|
+
this.resubTimeoutMs = resubTimeoutMs;
|
|
44
|
+
this.options = options;
|
|
45
|
+
this.receivingData = false;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async subscribe(
|
|
49
|
+
onChange: (accountId: PublicKey, data: T, context: Context) => void
|
|
50
|
+
): Promise<void> {
|
|
51
|
+
if (this.listenerId) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
this.onChange = onChange;
|
|
56
|
+
|
|
57
|
+
this.listenerId = this.program.provider.connection.onProgramAccountChange(
|
|
58
|
+
this.program.programId,
|
|
59
|
+
(keyedAccountInfo, context) => {
|
|
60
|
+
if (this.resubTimeoutMs) {
|
|
61
|
+
this.receivingData = true;
|
|
62
|
+
clearTimeout(this.timeoutId);
|
|
63
|
+
this.handleRpcResponse(context, keyedAccountInfo);
|
|
64
|
+
this.setTimeout();
|
|
65
|
+
} else {
|
|
66
|
+
this.handleRpcResponse(context, keyedAccountInfo);
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
this.options.commitment ??
|
|
70
|
+
(this.program.provider as AnchorProvider).opts.commitment,
|
|
71
|
+
this.options.filters
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
if (this.resubTimeoutMs) {
|
|
75
|
+
this.setTimeout();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
private setTimeout(): void {
|
|
80
|
+
if (!this.onChange) {
|
|
81
|
+
throw new Error('onChange callback function must be set');
|
|
82
|
+
}
|
|
83
|
+
this.timeoutId = setTimeout(async () => {
|
|
84
|
+
if (this.receivingData) {
|
|
85
|
+
console.log(
|
|
86
|
+
`No ws data from ${this.subscriptionName} in ${this.resubTimeoutMs}ms, resubscribing`
|
|
87
|
+
);
|
|
88
|
+
await this.unsubscribe();
|
|
89
|
+
this.receivingData = false;
|
|
90
|
+
await this.subscribe(this.onChange);
|
|
91
|
+
}
|
|
92
|
+
}, this.resubTimeoutMs);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
handleRpcResponse(
|
|
96
|
+
context: Context,
|
|
97
|
+
keyedAccountInfo: KeyedAccountInfo
|
|
98
|
+
): void {
|
|
99
|
+
const newSlot = context.slot;
|
|
100
|
+
let newBuffer: Buffer | undefined = undefined;
|
|
101
|
+
if (keyedAccountInfo) {
|
|
102
|
+
newBuffer = keyedAccountInfo.accountInfo.data;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (!this.bufferAndSlot) {
|
|
106
|
+
this.bufferAndSlot = {
|
|
107
|
+
buffer: newBuffer,
|
|
108
|
+
slot: newSlot,
|
|
109
|
+
};
|
|
110
|
+
if (newBuffer) {
|
|
111
|
+
const account = this.decodeBuffer(this.accountDiscriminator, newBuffer);
|
|
112
|
+
this.dataAndSlot = {
|
|
113
|
+
data: account,
|
|
114
|
+
slot: newSlot,
|
|
115
|
+
accountId: keyedAccountInfo.accountId,
|
|
116
|
+
};
|
|
117
|
+
this.onChange(keyedAccountInfo.accountId, account, context);
|
|
118
|
+
}
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (newSlot <= this.bufferAndSlot.slot) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const oldBuffer = this.bufferAndSlot.buffer;
|
|
127
|
+
if (newBuffer && (!oldBuffer || !newBuffer.equals(oldBuffer))) {
|
|
128
|
+
this.bufferAndSlot = {
|
|
129
|
+
buffer: newBuffer,
|
|
130
|
+
slot: newSlot,
|
|
131
|
+
};
|
|
132
|
+
const account = this.decodeBuffer(this.accountDiscriminator, newBuffer);
|
|
133
|
+
this.dataAndSlot = {
|
|
134
|
+
data: account,
|
|
135
|
+
slot: newSlot,
|
|
136
|
+
accountId: keyedAccountInfo.accountId,
|
|
137
|
+
};
|
|
138
|
+
this.onChange(keyedAccountInfo.accountId, account, context);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
unsubscribe(): Promise<void> {
|
|
143
|
+
if (this.listenerId) {
|
|
144
|
+
const promise =
|
|
145
|
+
this.program.provider.connection.removeAccountChangeListener(
|
|
146
|
+
this.listenerId
|
|
147
|
+
);
|
|
148
|
+
this.listenerId = undefined;
|
|
149
|
+
return promise;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
@@ -14,17 +14,23 @@ import { UserAccount } from '../types';
|
|
|
14
14
|
|
|
15
15
|
export class WebSocketUserAccountSubscriber implements UserAccountSubscriber {
|
|
16
16
|
isSubscribed: boolean;
|
|
17
|
+
reconnectTimeoutMs?: number;
|
|
17
18
|
program: Program;
|
|
18
19
|
eventEmitter: StrictEventEmitter<EventEmitter, UserAccountEvents>;
|
|
19
20
|
userAccountPublicKey: PublicKey;
|
|
20
21
|
|
|
21
22
|
userDataAccountSubscriber: AccountSubscriber<UserAccount>;
|
|
22
23
|
|
|
23
|
-
public constructor(
|
|
24
|
+
public constructor(
|
|
25
|
+
program: Program,
|
|
26
|
+
userAccountPublicKey: PublicKey,
|
|
27
|
+
reconnectTimeoutMs?: number
|
|
28
|
+
) {
|
|
24
29
|
this.isSubscribed = false;
|
|
25
30
|
this.program = program;
|
|
26
31
|
this.userAccountPublicKey = userAccountPublicKey;
|
|
27
32
|
this.eventEmitter = new EventEmitter();
|
|
33
|
+
this.reconnectTimeoutMs = reconnectTimeoutMs;
|
|
28
34
|
}
|
|
29
35
|
|
|
30
36
|
async subscribe(userAccount?: UserAccount): Promise<boolean> {
|
|
@@ -35,7 +41,9 @@ export class WebSocketUserAccountSubscriber implements UserAccountSubscriber {
|
|
|
35
41
|
this.userDataAccountSubscriber = new WebSocketAccountSubscriber(
|
|
36
42
|
'user',
|
|
37
43
|
this.program,
|
|
38
|
-
this.userAccountPublicKey
|
|
44
|
+
this.userAccountPublicKey,
|
|
45
|
+
undefined,
|
|
46
|
+
this.reconnectTimeoutMs
|
|
39
47
|
);
|
|
40
48
|
|
|
41
49
|
if (userAccount) {
|
|
@@ -16,17 +16,23 @@ export class WebSocketUserStatsAccountSubscriber
|
|
|
16
16
|
implements UserStatsAccountSubscriber
|
|
17
17
|
{
|
|
18
18
|
isSubscribed: boolean;
|
|
19
|
+
reconnectTimeoutMs?: number;
|
|
19
20
|
program: Program;
|
|
20
21
|
eventEmitter: StrictEventEmitter<EventEmitter, UserStatsAccountEvents>;
|
|
21
22
|
userStatsAccountPublicKey: PublicKey;
|
|
22
23
|
|
|
23
24
|
userStatsAccountSubscriber: AccountSubscriber<UserStatsAccount>;
|
|
24
25
|
|
|
25
|
-
public constructor(
|
|
26
|
+
public constructor(
|
|
27
|
+
program: Program,
|
|
28
|
+
userStatsAccountPublicKey: PublicKey,
|
|
29
|
+
reconnectTimeoutMs?: number
|
|
30
|
+
) {
|
|
26
31
|
this.isSubscribed = false;
|
|
27
32
|
this.program = program;
|
|
28
33
|
this.userStatsAccountPublicKey = userStatsAccountPublicKey;
|
|
29
34
|
this.eventEmitter = new EventEmitter();
|
|
35
|
+
this.reconnectTimeoutMs = reconnectTimeoutMs;
|
|
30
36
|
}
|
|
31
37
|
|
|
32
38
|
async subscribe(userStatsAccount?: UserStatsAccount): Promise<boolean> {
|
|
@@ -37,7 +43,9 @@ export class WebSocketUserStatsAccountSubscriber
|
|
|
37
43
|
this.userStatsAccountSubscriber = new WebSocketAccountSubscriber(
|
|
38
44
|
'userStats',
|
|
39
45
|
this.program,
|
|
40
|
-
this.userStatsAccountPublicKey
|
|
46
|
+
this.userStatsAccountPublicKey,
|
|
47
|
+
undefined,
|
|
48
|
+
this.reconnectTimeoutMs
|
|
41
49
|
);
|
|
42
50
|
|
|
43
51
|
if (userStatsAccount) {
|
|
@@ -4,48 +4,57 @@ import { getUserFilter, getUserWithAuctionFilter } from '../memcmp';
|
|
|
4
4
|
import StrictEventEmitter from 'strict-event-emitter-types';
|
|
5
5
|
import { EventEmitter } from 'events';
|
|
6
6
|
import { UserAccount } from '../types';
|
|
7
|
-
import { ConfirmOptions } from '@solana/web3.js';
|
|
7
|
+
import { ConfirmOptions, Context, PublicKey } from '@solana/web3.js';
|
|
8
|
+
import { WebSocketProgramAccountSubscriber } from '../accounts/webSocketProgramAccountSubscriber';
|
|
8
9
|
|
|
9
10
|
export class AuctionSubscriber {
|
|
10
11
|
private driftClient: DriftClient;
|
|
11
12
|
private opts: ConfirmOptions;
|
|
13
|
+
private resubTimeoutMs?: number;
|
|
12
14
|
|
|
13
15
|
eventEmitter: StrictEventEmitter<EventEmitter, AuctionSubscriberEvents>;
|
|
16
|
+
private subscriber: WebSocketProgramAccountSubscriber<UserAccount>;
|
|
14
17
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
constructor({ driftClient, opts }: AuctionSubscriberConfig) {
|
|
18
|
+
constructor({ driftClient, opts, resubTimeoutMs }: AuctionSubscriberConfig) {
|
|
18
19
|
this.driftClient = driftClient;
|
|
19
20
|
this.opts = opts || this.driftClient.opts;
|
|
20
21
|
this.eventEmitter = new EventEmitter();
|
|
22
|
+
this.resubTimeoutMs = resubTimeoutMs;
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
public async subscribe() {
|
|
24
|
-
this.
|
|
25
|
-
this.
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
26
|
+
if (!this.subscriber) {
|
|
27
|
+
this.subscriber = new WebSocketProgramAccountSubscriber<UserAccount>(
|
|
28
|
+
'AuctionSubscriber',
|
|
29
|
+
'User',
|
|
30
|
+
this.driftClient.program,
|
|
31
|
+
this.driftClient.program.account.user.coder.accounts.decode.bind(
|
|
32
|
+
this.driftClient.program.account.user.coder.accounts
|
|
33
|
+
),
|
|
34
|
+
{
|
|
35
|
+
filters: [getUserFilter(), getUserWithAuctionFilter()],
|
|
36
|
+
commitment: this.driftClient.opts.commitment,
|
|
37
|
+
},
|
|
38
|
+
this.resubTimeoutMs
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
await this.subscriber.subscribe(
|
|
43
|
+
(accountId: PublicKey, data: UserAccount, context: Context) => {
|
|
32
44
|
this.eventEmitter.emit(
|
|
33
45
|
'onAccountUpdate',
|
|
34
|
-
|
|
35
|
-
|
|
46
|
+
data,
|
|
47
|
+
accountId,
|
|
36
48
|
context.slot
|
|
37
49
|
);
|
|
38
|
-
}
|
|
39
|
-
this.driftClient.opts.commitment,
|
|
40
|
-
[getUserFilter(), getUserWithAuctionFilter()]
|
|
50
|
+
}
|
|
41
51
|
);
|
|
42
52
|
}
|
|
43
53
|
|
|
44
54
|
public async unsubscribe() {
|
|
45
|
-
if (this.
|
|
46
|
-
|
|
47
|
-
this.websocketId
|
|
48
|
-
);
|
|
55
|
+
if (!this.subscriber) {
|
|
56
|
+
return;
|
|
49
57
|
}
|
|
58
|
+
this.subscriber.unsubscribe();
|
|
50
59
|
}
|
|
51
60
|
}
|
package/src/driftClient.ts
CHANGED
|
@@ -278,7 +278,8 @@ export class DriftClient {
|
|
|
278
278
|
config.perpMarketIndexes ?? [],
|
|
279
279
|
config.spotMarketIndexes ?? [],
|
|
280
280
|
config.oracleInfos ?? [],
|
|
281
|
-
noMarketsAndOraclesSpecified
|
|
281
|
+
noMarketsAndOraclesSpecified,
|
|
282
|
+
config.accountSubscription?.resubTimeoutMs
|
|
282
283
|
);
|
|
283
284
|
}
|
|
284
285
|
this.eventEmitter = this.accountSubscriber.eventEmitter;
|
|
@@ -3424,6 +3425,7 @@ export class DriftClient {
|
|
|
3424
3425
|
reduceOnly,
|
|
3425
3426
|
txParams,
|
|
3426
3427
|
v6,
|
|
3428
|
+
onlyDirectRoutes = false,
|
|
3427
3429
|
}: {
|
|
3428
3430
|
jupiterClient: JupiterClient;
|
|
3429
3431
|
outMarketIndex: number;
|
|
@@ -3436,6 +3438,7 @@ export class DriftClient {
|
|
|
3436
3438
|
route?: Route;
|
|
3437
3439
|
reduceOnly?: SwapReduceOnly;
|
|
3438
3440
|
txParams?: TxParams;
|
|
3441
|
+
onlyDirectRoutes?: boolean;
|
|
3439
3442
|
v6?: {
|
|
3440
3443
|
quote?: QuoteResponse;
|
|
3441
3444
|
};
|
|
@@ -3455,6 +3458,7 @@ export class DriftClient {
|
|
|
3455
3458
|
swapMode,
|
|
3456
3459
|
quote: v6.quote,
|
|
3457
3460
|
reduceOnly,
|
|
3461
|
+
onlyDirectRoutes,
|
|
3458
3462
|
});
|
|
3459
3463
|
ixs = res.ixs;
|
|
3460
3464
|
lookupTables = res.lookupTables;
|
package/src/driftClientConfig.ts
CHANGED
package/src/idl/drift.json
CHANGED
|
@@ -6314,6 +6314,24 @@
|
|
|
6314
6314
|
]
|
|
6315
6315
|
}
|
|
6316
6316
|
},
|
|
6317
|
+
{
|
|
6318
|
+
"name": "MarketIdentifier",
|
|
6319
|
+
"type": {
|
|
6320
|
+
"kind": "struct",
|
|
6321
|
+
"fields": [
|
|
6322
|
+
{
|
|
6323
|
+
"name": "marketType",
|
|
6324
|
+
"type": {
|
|
6325
|
+
"defined": "MarketType"
|
|
6326
|
+
}
|
|
6327
|
+
},
|
|
6328
|
+
{
|
|
6329
|
+
"name": "marketIndex",
|
|
6330
|
+
"type": "u16"
|
|
6331
|
+
}
|
|
6332
|
+
]
|
|
6333
|
+
}
|
|
6334
|
+
},
|
|
6317
6335
|
{
|
|
6318
6336
|
"name": "HistoricalOracleData",
|
|
6319
6337
|
"type": {
|
|
@@ -8198,6 +8216,34 @@
|
|
|
8198
8216
|
]
|
|
8199
8217
|
}
|
|
8200
8218
|
},
|
|
8219
|
+
{
|
|
8220
|
+
"name": "MarginCalculationMode",
|
|
8221
|
+
"type": {
|
|
8222
|
+
"kind": "enum",
|
|
8223
|
+
"variants": [
|
|
8224
|
+
{
|
|
8225
|
+
"name": "Standard"
|
|
8226
|
+
},
|
|
8227
|
+
{
|
|
8228
|
+
"name": "Liquidation",
|
|
8229
|
+
"fields": [
|
|
8230
|
+
{
|
|
8231
|
+
"name": "margin_buffer",
|
|
8232
|
+
"type": "u128"
|
|
8233
|
+
},
|
|
8234
|
+
{
|
|
8235
|
+
"name": "market_to_track_margin_requirement",
|
|
8236
|
+
"type": {
|
|
8237
|
+
"option": {
|
|
8238
|
+
"defined": "MarketIdentifier"
|
|
8239
|
+
}
|
|
8240
|
+
}
|
|
8241
|
+
}
|
|
8242
|
+
]
|
|
8243
|
+
}
|
|
8244
|
+
]
|
|
8245
|
+
}
|
|
8246
|
+
},
|
|
8201
8247
|
{
|
|
8202
8248
|
"name": "OracleSource",
|
|
8203
8249
|
"type": {
|
|
@@ -10781,6 +10827,11 @@
|
|
|
10781
10827
|
"code": 6254,
|
|
10782
10828
|
"name": "UserReduceOnly",
|
|
10783
10829
|
"msg": "UserReduceOnly"
|
|
10830
|
+
},
|
|
10831
|
+
{
|
|
10832
|
+
"code": 6255,
|
|
10833
|
+
"name": "InvalidMarginCalculation",
|
|
10834
|
+
"msg": "InvalidMarginCalculation"
|
|
10784
10835
|
}
|
|
10785
10836
|
]
|
|
10786
10837
|
}
|
|
@@ -275,6 +275,7 @@ export class JupiterClient {
|
|
|
275
275
|
inputMint,
|
|
276
276
|
outputMint,
|
|
277
277
|
amount,
|
|
278
|
+
maxAccounts = 52, // 52 is an estimated amount with buffer
|
|
278
279
|
slippageBps = 50,
|
|
279
280
|
swapMode = 'ExactIn',
|
|
280
281
|
onlyDirectRoutes = false,
|
|
@@ -282,6 +283,7 @@ export class JupiterClient {
|
|
|
282
283
|
inputMint: PublicKey;
|
|
283
284
|
outputMint: PublicKey;
|
|
284
285
|
amount: BN;
|
|
286
|
+
maxAccounts?: number;
|
|
285
287
|
slippageBps?: number;
|
|
286
288
|
swapMode?: SwapMode;
|
|
287
289
|
onlyDirectRoutes?: boolean;
|
|
@@ -293,6 +295,7 @@ export class JupiterClient {
|
|
|
293
295
|
slippageBps: slippageBps.toString(),
|
|
294
296
|
swapMode,
|
|
295
297
|
onlyDirectRoutes: onlyDirectRoutes.toString(),
|
|
298
|
+
maxAccounts: maxAccounts.toString(),
|
|
296
299
|
}).toString();
|
|
297
300
|
const quote = await (await fetch(`${this.url}/v6/quote?${params}`)).json();
|
|
298
301
|
return quote;
|
package/src/math/amm.ts
CHANGED
|
@@ -471,12 +471,19 @@ export function calculateVolSpreadBN(
|
|
|
471
471
|
clampMax
|
|
472
472
|
);
|
|
473
473
|
|
|
474
|
+
// only consider confidence interval at full value when above 25 bps
|
|
475
|
+
let confComponent = lastOracleConfPct;
|
|
476
|
+
|
|
477
|
+
if (lastOracleConfPct.lte(PRICE_PRECISION.div(new BN(400)))) {
|
|
478
|
+
confComponent = lastOracleConfPct.div(new BN(10));
|
|
479
|
+
}
|
|
480
|
+
|
|
474
481
|
const longVolSpread = BN.max(
|
|
475
|
-
|
|
482
|
+
confComponent,
|
|
476
483
|
volSpread.mul(longVolSpreadFactor).div(PERCENTAGE_PRECISION)
|
|
477
484
|
);
|
|
478
485
|
const shortVolSpread = BN.max(
|
|
479
|
-
|
|
486
|
+
confComponent,
|
|
480
487
|
volSpread.mul(shortVolSpreadFactor).div(PERCENTAGE_PRECISION)
|
|
481
488
|
);
|
|
482
489
|
|