@drift-labs/jit-proxy 0.12.65 → 0.12.67
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/jitProxyClient.d.ts +9 -0
- package/lib/jitProxyClient.js +56 -0
- package/lib/jitter/baseJitter.d.ts +9 -2
- package/lib/jitter/baseJitter.js +83 -1
- package/lib/jitter/jitterShotgun.d.ts +6 -2
- package/lib/jitter/jitterShotgun.js +68 -1
- package/lib/jitter/jitterSniper.d.ts +5 -2
- package/lib/jitter/jitterSniper.js +136 -1
- package/lib/types/jit_proxy.d.ts +103 -1
- package/lib/types/jit_proxy.js +103 -1
- package/package.json +4 -3
- package/src/jitProxyClient.ts +101 -0
- package/src/jitter/baseJitter.ts +173 -0
- package/src/jitter/jitterShotgun.ts +93 -0
- package/src/jitter/jitterSniper.ts +196 -0
- package/src/types/jit_proxy.ts +206 -2
package/lib/jitProxyClient.d.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { BN, DriftClient, MakerInfo, MarketType, PostOnlyParams, ReferrerInfo, TxParams, UserAccount } from '@drift-labs/sdk';
|
|
3
3
|
import { PublicKey, TransactionInstruction } from '@solana/web3.js';
|
|
4
4
|
import { TxSigAndSlot } from '@drift-labs/sdk';
|
|
5
|
+
import { SignedSwiftOrderParams } from '@drift-labs/sdk/lib/node/swift/types';
|
|
5
6
|
export type JitIxParams = {
|
|
6
7
|
takerKey: PublicKey;
|
|
7
8
|
takerStatsKey: PublicKey;
|
|
@@ -16,6 +17,12 @@ export type JitIxParams = {
|
|
|
16
17
|
referrerInfo?: ReferrerInfo;
|
|
17
18
|
subAccountId?: number;
|
|
18
19
|
};
|
|
20
|
+
export type JitSwiftIxParams = JitIxParams & {
|
|
21
|
+
authorityToUse: PublicKey;
|
|
22
|
+
signedSwiftOrderParams: SignedSwiftOrderParams;
|
|
23
|
+
uuid: Uint8Array;
|
|
24
|
+
marketIndex: number;
|
|
25
|
+
};
|
|
19
26
|
export declare class PriceType {
|
|
20
27
|
static readonly LIMIT: {
|
|
21
28
|
limit: {};
|
|
@@ -38,7 +45,9 @@ export declare class JitProxyClient {
|
|
|
38
45
|
programId: PublicKey;
|
|
39
46
|
});
|
|
40
47
|
jit(params: JitIxParams, txParams?: TxParams): Promise<TxSigAndSlot>;
|
|
48
|
+
jitSwift(params: JitSwiftIxParams, txParams?: TxParams, precedingIxs?: TransactionInstruction[]): Promise<TxSigAndSlot>;
|
|
41
49
|
getJitIx({ takerKey, takerStatsKey, taker, takerOrderId, maxPosition, minPosition, bid, ask, postOnly, priceType, referrerInfo, subAccountId, }: JitIxParams): Promise<TransactionInstruction>;
|
|
50
|
+
getJitSwiftIx({ takerKey, takerStatsKey, taker, maxPosition, minPosition, bid, ask, postOnly, priceType, referrerInfo, subAccountId, uuid, marketIndex, }: JitSwiftIxParams): Promise<TransactionInstruction>;
|
|
42
51
|
getCheckOrderConstraintIx({ subAccountId, orderConstraints, }: {
|
|
43
52
|
subAccountId: number;
|
|
44
53
|
orderConstraints: OrderConstraint[];
|
package/lib/jitProxyClient.js
CHANGED
|
@@ -19,6 +19,16 @@ class JitProxyClient {
|
|
|
19
19
|
const tx = await this.driftClient.buildTransaction([ix], txParams);
|
|
20
20
|
return await this.driftClient.sendTransaction(tx);
|
|
21
21
|
}
|
|
22
|
+
async jitSwift(params, txParams, precedingIxs) {
|
|
23
|
+
const swiftTakerIxs = await this.driftClient.getPlaceSwiftTakerPerpOrderIxs(params.signedSwiftOrderParams, params.marketIndex, {
|
|
24
|
+
taker: params.takerKey,
|
|
25
|
+
takerStats: params.takerStatsKey,
|
|
26
|
+
takerUserAccount: params.taker,
|
|
27
|
+
}, params.authorityToUse, precedingIxs);
|
|
28
|
+
const ix = await this.getJitSwiftIx(params);
|
|
29
|
+
const tx = await this.driftClient.buildTransaction([...swiftTakerIxs, ix], txParams);
|
|
30
|
+
return await this.driftClient.sendTransaction(tx);
|
|
31
|
+
}
|
|
22
32
|
async getJitIx({ takerKey, takerStatsKey, taker, takerOrderId, maxPosition, minPosition, bid, ask, postOnly = null, priceType = PriceType.LIMIT, referrerInfo, subAccountId, }) {
|
|
23
33
|
subAccountId =
|
|
24
34
|
subAccountId !== undefined
|
|
@@ -80,6 +90,52 @@ class JitProxyClient {
|
|
|
80
90
|
.remainingAccounts(remainingAccounts)
|
|
81
91
|
.instruction();
|
|
82
92
|
}
|
|
93
|
+
async getJitSwiftIx({ takerKey, takerStatsKey, taker, maxPosition, minPosition, bid, ask, postOnly = null, priceType = PriceType.LIMIT, referrerInfo, subAccountId, uuid, marketIndex, }) {
|
|
94
|
+
subAccountId =
|
|
95
|
+
subAccountId !== undefined
|
|
96
|
+
? subAccountId
|
|
97
|
+
: this.driftClient.activeSubAccountId;
|
|
98
|
+
const remainingAccounts = this.driftClient.getRemainingAccounts({
|
|
99
|
+
userAccounts: [taker, this.driftClient.getUserAccount(subAccountId)],
|
|
100
|
+
writableSpotMarketIndexes: [],
|
|
101
|
+
writablePerpMarketIndexes: [marketIndex],
|
|
102
|
+
});
|
|
103
|
+
if (referrerInfo) {
|
|
104
|
+
remainingAccounts.push({
|
|
105
|
+
pubkey: referrerInfo.referrer,
|
|
106
|
+
isWritable: true,
|
|
107
|
+
isSigner: false,
|
|
108
|
+
});
|
|
109
|
+
remainingAccounts.push({
|
|
110
|
+
pubkey: referrerInfo.referrerStats,
|
|
111
|
+
isWritable: true,
|
|
112
|
+
isSigner: false,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
const jitSwiftParams = {
|
|
116
|
+
swiftOrderUuid: Array.from(uuid),
|
|
117
|
+
maxPosition,
|
|
118
|
+
minPosition,
|
|
119
|
+
bid,
|
|
120
|
+
ask,
|
|
121
|
+
postOnly,
|
|
122
|
+
priceType,
|
|
123
|
+
};
|
|
124
|
+
return this.program.methods
|
|
125
|
+
.jitSwift(jitSwiftParams)
|
|
126
|
+
.accounts({
|
|
127
|
+
taker: takerKey,
|
|
128
|
+
takerStats: takerStatsKey,
|
|
129
|
+
takerSwiftUserOrders: (0, sdk_1.getSwiftUserAccountPublicKey)(this.driftClient.program.programId, taker.authority),
|
|
130
|
+
authority: this.driftClient.wallet.payer.publicKey,
|
|
131
|
+
state: await this.driftClient.getStatePublicKey(),
|
|
132
|
+
user: await this.driftClient.getUserAccountPublicKey(subAccountId),
|
|
133
|
+
userStats: this.driftClient.getUserStatsAccountPublicKey(),
|
|
134
|
+
driftProgram: this.driftClient.program.programId,
|
|
135
|
+
})
|
|
136
|
+
.remainingAccounts(remainingAccounts)
|
|
137
|
+
.instruction();
|
|
138
|
+
}
|
|
83
139
|
async getCheckOrderConstraintIx({ subAccountId, orderConstraints, }) {
|
|
84
140
|
subAccountId =
|
|
85
141
|
subAccountId !== undefined
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/// <reference types="bn.js" />
|
|
2
2
|
import { JitProxyClient, PriceType } from '../jitProxyClient';
|
|
3
3
|
import { PublicKey } from '@solana/web3.js';
|
|
4
|
-
import { AuctionSubscriber, BN, DriftClient, Order, PostOnlyParams, UserAccount, UserStatsMap } from '@drift-labs/sdk';
|
|
4
|
+
import { AuctionSubscriber, BN, DriftClient, Order, PostOnlyParams, SlotSubscriber, SwiftOrderSubscriber, UserAccount, UserStatsMap } from '@drift-labs/sdk';
|
|
5
|
+
import { SignedSwiftOrderParams } from '@drift-labs/sdk/lib/node/swift/types';
|
|
5
6
|
export type UserFilter = (userAccount: UserAccount, userKey: string, order: Order) => boolean;
|
|
6
7
|
export type JitParams = {
|
|
7
8
|
bid: BN;
|
|
@@ -14,6 +15,8 @@ export type JitParams = {
|
|
|
14
15
|
};
|
|
15
16
|
export declare abstract class BaseJitter {
|
|
16
17
|
auctionSubscriber: AuctionSubscriber;
|
|
18
|
+
swiftOrderSubscriber: SwiftOrderSubscriber;
|
|
19
|
+
slotSubscriber: SlotSubscriber;
|
|
17
20
|
driftClient: DriftClient;
|
|
18
21
|
jitProxyClient: JitProxyClient;
|
|
19
22
|
userStatsMap: UserStatsMap;
|
|
@@ -24,16 +27,20 @@ export declare abstract class BaseJitter {
|
|
|
24
27
|
userFilter: UserFilter;
|
|
25
28
|
computeUnits: number;
|
|
26
29
|
computeUnitsPrice: number;
|
|
27
|
-
constructor({ auctionSubscriber, jitProxyClient, driftClient, userStatsMap, }: {
|
|
30
|
+
constructor({ auctionSubscriber, jitProxyClient, driftClient, userStatsMap, swiftOrderSubscriber, slotSubscriber, }: {
|
|
28
31
|
driftClient: DriftClient;
|
|
29
32
|
auctionSubscriber: AuctionSubscriber;
|
|
30
33
|
jitProxyClient: JitProxyClient;
|
|
31
34
|
userStatsMap: UserStatsMap;
|
|
35
|
+
swiftOrderSubscriber?: SwiftOrderSubscriber;
|
|
36
|
+
slotSubscriber?: SlotSubscriber;
|
|
32
37
|
});
|
|
33
38
|
subscribe(): Promise<void>;
|
|
34
39
|
createTryFill(taker: UserAccount, takerKey: PublicKey, takerStatsKey: PublicKey, order: Order, orderSignature: string): () => Promise<void>;
|
|
40
|
+
createTrySwiftFill(authorityToUse: PublicKey, signedSwiftOrderParams: SignedSwiftOrderParams, uuid: Uint8Array, taker: UserAccount, takerKey: PublicKey, takerStatsKey: PublicKey, order: Order, orderSignature: string, marketIndex: number): () => Promise<void>;
|
|
35
41
|
deleteOnGoingAuction(orderSignature: string): void;
|
|
36
42
|
getOrderSignatures(takerKey: string, orderId: number): string;
|
|
43
|
+
private convertUuidToNumber;
|
|
37
44
|
updatePerpParams(marketIndex: number, params: JitParams): void;
|
|
38
45
|
updateSpotParams(marketIndex: number, params: JitParams): void;
|
|
39
46
|
setUserFilter(userFilter: UserFilter | undefined): void;
|
package/lib/jitter/baseJitter.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.BaseJitter = void 0;
|
|
4
|
+
const web3_js_1 = require("@solana/web3.js");
|
|
4
5
|
const sdk_1 = require("@drift-labs/sdk");
|
|
6
|
+
const tweetnacl_util_1 = require("tweetnacl-util");
|
|
5
7
|
class BaseJitter {
|
|
6
|
-
constructor({ auctionSubscriber, jitProxyClient, driftClient, userStatsMap, }) {
|
|
8
|
+
constructor({ auctionSubscriber, jitProxyClient, driftClient, userStatsMap, swiftOrderSubscriber, slotSubscriber, }) {
|
|
7
9
|
this.perpParams = new Map();
|
|
8
10
|
this.spotParams = new Map();
|
|
9
11
|
this.seenOrders = new Set();
|
|
@@ -14,8 +16,14 @@ class BaseJitter {
|
|
|
14
16
|
this.userStatsMap =
|
|
15
17
|
userStatsMap ||
|
|
16
18
|
new sdk_1.UserStatsMap(this.driftClient, new sdk_1.BulkAccountLoader(this.driftClient.connection, 'confirmed', 0));
|
|
19
|
+
this.slotSubscriber = slotSubscriber;
|
|
20
|
+
this.swiftOrderSubscriber = swiftOrderSubscriber;
|
|
21
|
+
if (this.swiftOrderSubscriber && !this.slotSubscriber) {
|
|
22
|
+
throw new Error('Slot subscriber is required for swift order subscriber');
|
|
23
|
+
}
|
|
17
24
|
}
|
|
18
25
|
async subscribe() {
|
|
26
|
+
var _a, _b;
|
|
19
27
|
await this.driftClient.subscribe();
|
|
20
28
|
await this.auctionSubscriber.subscribe();
|
|
21
29
|
this.auctionSubscriber.eventEmitter.on('onAccountUpdate', async (taker, takerKey, slot) => {
|
|
@@ -69,10 +77,78 @@ class BaseJitter {
|
|
|
69
77
|
}
|
|
70
78
|
}
|
|
71
79
|
});
|
|
80
|
+
await ((_a = this.slotSubscriber) === null || _a === void 0 ? void 0 : _a.subscribe());
|
|
81
|
+
await ((_b = this.swiftOrderSubscriber) === null || _b === void 0 ? void 0 : _b.subscribe(async (orderMessageRaw, swiftOrderParamsMessage) => {
|
|
82
|
+
var _a, _b, _c;
|
|
83
|
+
const swiftOrderParamsBufHex = Buffer.from(orderMessageRaw['order_message']);
|
|
84
|
+
const swiftOrderParamsBuf = Buffer.from(orderMessageRaw['order_message'], 'hex');
|
|
85
|
+
const { swiftOrderParams, subAccountId: takerSubaccountId, } = this.driftClient.decodeSwiftOrderParamsMessage(swiftOrderParamsBuf);
|
|
86
|
+
const takerAuthority = new web3_js_1.PublicKey(orderMessageRaw['taker_authority']);
|
|
87
|
+
const takerUserPubkey = await (0, sdk_1.getUserAccountPublicKey)(this.driftClient.program.programId, takerAuthority, takerSubaccountId);
|
|
88
|
+
const takerUserPubkeyString = takerUserPubkey.toBase58();
|
|
89
|
+
const takerUserAccount = (await this.swiftOrderSubscriber.userMap.mustGet(takerUserPubkey.toString())).getUserAccount();
|
|
90
|
+
const swiftOrder = {
|
|
91
|
+
status: sdk_1.OrderStatus.OPEN,
|
|
92
|
+
orderType: swiftOrderParams.orderType,
|
|
93
|
+
orderId: this.convertUuidToNumber(orderMessageRaw['uuid']),
|
|
94
|
+
slot: swiftOrderParamsMessage.slot,
|
|
95
|
+
marketIndex: swiftOrderParams.marketIndex,
|
|
96
|
+
marketType: sdk_1.MarketType.PERP,
|
|
97
|
+
baseAssetAmount: swiftOrderParams.baseAssetAmount,
|
|
98
|
+
auctionDuration: swiftOrderParams.auctionDuration,
|
|
99
|
+
auctionStartPrice: swiftOrderParams.auctionStartPrice,
|
|
100
|
+
auctionEndPrice: swiftOrderParams.auctionEndPrice,
|
|
101
|
+
immediateOrCancel: swiftOrderParams.immediateOrCancel,
|
|
102
|
+
direction: swiftOrderParams.direction,
|
|
103
|
+
postOnly: false,
|
|
104
|
+
oraclePriceOffset: (_a = swiftOrderParams.oraclePriceOffset) !== null && _a !== void 0 ? _a : 0,
|
|
105
|
+
maxTs: (_b = swiftOrderParams.maxTs) !== null && _b !== void 0 ? _b : sdk_1.ZERO,
|
|
106
|
+
reduceOnly: swiftOrderParams.reduceOnly,
|
|
107
|
+
triggerCondition: swiftOrderParams.triggerCondition,
|
|
108
|
+
// Rest are not necessary and set for type conforming
|
|
109
|
+
price: sdk_1.ZERO,
|
|
110
|
+
existingPositionDirection: sdk_1.PositionDirection.LONG,
|
|
111
|
+
triggerPrice: sdk_1.ZERO,
|
|
112
|
+
baseAssetAmountFilled: sdk_1.ZERO,
|
|
113
|
+
quoteAssetAmountFilled: sdk_1.ZERO,
|
|
114
|
+
quoteAssetAmount: sdk_1.ZERO,
|
|
115
|
+
userOrderId: 0,
|
|
116
|
+
};
|
|
117
|
+
swiftOrder.price = (0, sdk_1.getAuctionPrice)(swiftOrder, (_c = this.slotSubscriber) === null || _c === void 0 ? void 0 : _c.getSlot(), this.driftClient.getOracleDataForPerpMarket(swiftOrder.marketIndex)
|
|
118
|
+
.price);
|
|
119
|
+
if (this.userFilter) {
|
|
120
|
+
if (this.userFilter(takerUserAccount, takerUserPubkeyString, swiftOrder)) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
const orderSignature = this.getOrderSignatures(takerUserPubkeyString, swiftOrder.orderId);
|
|
125
|
+
if (this.seenOrders.has(orderSignature)) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
this.seenOrders.add(orderSignature);
|
|
129
|
+
if (this.onGoingAuctions.has(orderSignature)) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
if (!this.perpParams.has(swiftOrder.marketIndex)) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
const perpMarketAccount = this.driftClient.getPerpMarketAccount(swiftOrder.marketIndex);
|
|
136
|
+
if (swiftOrder.baseAssetAmount.lt(perpMarketAccount.amm.minOrderSize)) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
const promise = this.createTrySwiftFill(takerAuthority, {
|
|
140
|
+
orderParams: swiftOrderParamsBufHex,
|
|
141
|
+
signature: Buffer.from(orderMessageRaw['order_signature'], 'base64'),
|
|
142
|
+
}, (0, tweetnacl_util_1.decodeUTF8)(orderMessageRaw['uuid']), takerUserAccount, takerUserPubkey, (0, sdk_1.getUserStatsAccountPublicKey)(this.driftClient.program.programId, takerUserAccount.authority), swiftOrder, orderSignature, orderMessageRaw['market_index']).bind(this)();
|
|
143
|
+
this.onGoingAuctions.set(orderSignature, promise);
|
|
144
|
+
}));
|
|
72
145
|
}
|
|
73
146
|
createTryFill(taker, takerKey, takerStatsKey, order, orderSignature) {
|
|
74
147
|
throw new Error('Not implemented');
|
|
75
148
|
}
|
|
149
|
+
createTrySwiftFill(authorityToUse, signedSwiftOrderParams, uuid, taker, takerKey, takerStatsKey, order, orderSignature, marketIndex) {
|
|
150
|
+
throw new Error('Not implemented');
|
|
151
|
+
}
|
|
76
152
|
deleteOnGoingAuction(orderSignature) {
|
|
77
153
|
this.onGoingAuctions.delete(orderSignature);
|
|
78
154
|
this.seenOrders.delete(orderSignature);
|
|
@@ -80,6 +156,12 @@ class BaseJitter {
|
|
|
80
156
|
getOrderSignatures(takerKey, orderId) {
|
|
81
157
|
return `${takerKey}-${orderId}`;
|
|
82
158
|
}
|
|
159
|
+
convertUuidToNumber(uuid) {
|
|
160
|
+
return uuid
|
|
161
|
+
.split('')
|
|
162
|
+
.reduce((n, c) => n * 64 +
|
|
163
|
+
'_~0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.indexOf(c), 0);
|
|
164
|
+
}
|
|
83
165
|
updatePerpParams(marketIndex, params) {
|
|
84
166
|
this.perpParams.set(marketIndex, params);
|
|
85
167
|
}
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import { JitProxyClient } from '../jitProxyClient';
|
|
2
2
|
import { PublicKey } from '@solana/web3.js';
|
|
3
|
-
import { AuctionSubscriber, DriftClient, Order, UserAccount, UserStatsMap } from '@drift-labs/sdk';
|
|
3
|
+
import { AuctionSubscriber, DriftClient, Order, SlotSubscriber, SwiftOrderSubscriber, UserAccount, UserStatsMap } from '@drift-labs/sdk';
|
|
4
4
|
import { BaseJitter } from './baseJitter';
|
|
5
|
+
import { SignedSwiftOrderParams } from '@drift-labs/sdk/lib/node/swift/types';
|
|
5
6
|
export declare class JitterShotgun extends BaseJitter {
|
|
6
|
-
constructor({ auctionSubscriber, jitProxyClient, driftClient, userStatsMap, }: {
|
|
7
|
+
constructor({ auctionSubscriber, jitProxyClient, driftClient, userStatsMap, swiftOrderSubscriber, slotSubscriber, }: {
|
|
7
8
|
driftClient: DriftClient;
|
|
8
9
|
auctionSubscriber: AuctionSubscriber;
|
|
9
10
|
jitProxyClient: JitProxyClient;
|
|
10
11
|
userStatsMap?: UserStatsMap;
|
|
12
|
+
swiftOrderSubscriber?: SwiftOrderSubscriber;
|
|
13
|
+
slotSubscriber?: SlotSubscriber;
|
|
11
14
|
});
|
|
12
15
|
createTryFill(taker: UserAccount, takerKey: PublicKey, takerStatsKey: PublicKey, order: Order, orderSignature: string): () => Promise<void>;
|
|
16
|
+
createTrySwiftFill(authorityToUse: PublicKey, signedSwiftOrderParams: SignedSwiftOrderParams, uuid: Uint8Array, taker: UserAccount, takerKey: PublicKey, takerStatsKey: PublicKey, order: Order, orderSignature: string, marketIndex: number): () => Promise<void>;
|
|
13
17
|
}
|
|
@@ -4,12 +4,14 @@ exports.JitterShotgun = void 0;
|
|
|
4
4
|
const sdk_1 = require("@drift-labs/sdk");
|
|
5
5
|
const baseJitter_1 = require("./baseJitter");
|
|
6
6
|
class JitterShotgun extends baseJitter_1.BaseJitter {
|
|
7
|
-
constructor({ auctionSubscriber, jitProxyClient, driftClient, userStatsMap, }) {
|
|
7
|
+
constructor({ auctionSubscriber, jitProxyClient, driftClient, userStatsMap, swiftOrderSubscriber, slotSubscriber, }) {
|
|
8
8
|
super({
|
|
9
9
|
auctionSubscriber,
|
|
10
10
|
jitProxyClient,
|
|
11
11
|
driftClient,
|
|
12
12
|
userStatsMap,
|
|
13
|
+
swiftOrderSubscriber,
|
|
14
|
+
slotSubscriber,
|
|
13
15
|
});
|
|
14
16
|
}
|
|
15
17
|
createTryFill(taker, takerKey, takerStatsKey, order, orderSignature) {
|
|
@@ -72,6 +74,71 @@ class JitterShotgun extends baseJitter_1.BaseJitter {
|
|
|
72
74
|
this.deleteOnGoingAuction(orderSignature);
|
|
73
75
|
};
|
|
74
76
|
}
|
|
77
|
+
createTrySwiftFill(authorityToUse, signedSwiftOrderParams, uuid, taker, takerKey, takerStatsKey, order, orderSignature, marketIndex) {
|
|
78
|
+
return async () => {
|
|
79
|
+
var _a;
|
|
80
|
+
let i = 0;
|
|
81
|
+
const takerStats = await this.userStatsMap.mustGet(taker.authority.toString());
|
|
82
|
+
const referrerInfo = takerStats.getReferrerInfo();
|
|
83
|
+
// assumes each preflight simulation takes ~1 slot
|
|
84
|
+
while (i < order.auctionDuration) {
|
|
85
|
+
const params = this.perpParams.get(order.marketIndex);
|
|
86
|
+
if (!params) {
|
|
87
|
+
this.deleteOnGoingAuction(orderSignature);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const txParams = {
|
|
91
|
+
computeUnits: this.computeUnits,
|
|
92
|
+
computeUnitsPrice: this.computeUnitsPrice,
|
|
93
|
+
};
|
|
94
|
+
console.log(`Trying to fill ${orderSignature}`);
|
|
95
|
+
try {
|
|
96
|
+
const { txSig } = await this.jitProxyClient.jitSwift({
|
|
97
|
+
takerKey,
|
|
98
|
+
takerStatsKey,
|
|
99
|
+
taker,
|
|
100
|
+
takerOrderId: order.orderId,
|
|
101
|
+
maxPosition: params.maxPosition,
|
|
102
|
+
minPosition: params.minPosition,
|
|
103
|
+
bid: params.bid,
|
|
104
|
+
ask: params.ask,
|
|
105
|
+
postOnly: (_a = params.postOnlyParams) !== null && _a !== void 0 ? _a : sdk_1.PostOnlyParams.MUST_POST_ONLY,
|
|
106
|
+
priceType: params.priceType,
|
|
107
|
+
referrerInfo,
|
|
108
|
+
subAccountId: params.subAccountId,
|
|
109
|
+
authorityToUse,
|
|
110
|
+
signedSwiftOrderParams,
|
|
111
|
+
uuid,
|
|
112
|
+
marketIndex,
|
|
113
|
+
}, txParams);
|
|
114
|
+
console.log(`Successfully sent tx for ${orderSignature} txSig ${txSig}`);
|
|
115
|
+
await sleep(10000);
|
|
116
|
+
this.deleteOnGoingAuction(orderSignature);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
catch (e) {
|
|
120
|
+
console.error(`Failed to fill ${orderSignature}`);
|
|
121
|
+
console.log(e);
|
|
122
|
+
if (e.message.includes('0x1770') || e.message.includes('0x1771')) {
|
|
123
|
+
console.log('Order does not cross params yet, retrying');
|
|
124
|
+
}
|
|
125
|
+
else if (e.message.includes('0x1779')) {
|
|
126
|
+
console.log('Order could not fill');
|
|
127
|
+
}
|
|
128
|
+
else if (e.message.includes('0x1793')) {
|
|
129
|
+
console.log('Oracle invalid, retrying');
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
await sleep(10000);
|
|
133
|
+
this.deleteOnGoingAuction(orderSignature);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
i++;
|
|
138
|
+
}
|
|
139
|
+
this.deleteOnGoingAuction(orderSignature);
|
|
140
|
+
};
|
|
141
|
+
}
|
|
75
142
|
}
|
|
76
143
|
exports.JitterShotgun = JitterShotgun;
|
|
77
144
|
function sleep(ms) {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { JitProxyClient } from '../jitProxyClient';
|
|
2
2
|
import { PublicKey } from '@solana/web3.js';
|
|
3
|
-
import { AuctionSubscriber, DriftClient, OraclePriceData, Order, SlotSubscriber, UserAccount, UserStatsMap } from '@drift-labs/sdk';
|
|
3
|
+
import { AuctionSubscriber, DriftClient, OraclePriceData, Order, SlotSubscriber, SwiftOrderSubscriber, UserAccount, UserStatsMap } from '@drift-labs/sdk';
|
|
4
4
|
import { BaseJitter } from './baseJitter';
|
|
5
|
+
import { SignedSwiftOrderParams } from '@drift-labs/sdk/lib/node/swift/types';
|
|
5
6
|
type AuctionAndOrderDetails = {
|
|
6
7
|
slotsTilCross: number;
|
|
7
8
|
willCross: boolean;
|
|
@@ -15,14 +16,16 @@ type AuctionAndOrderDetails = {
|
|
|
15
16
|
export declare class JitterSniper extends BaseJitter {
|
|
16
17
|
slotSubscriber: SlotSubscriber;
|
|
17
18
|
userStatsMap: UserStatsMap;
|
|
18
|
-
constructor({ auctionSubscriber, slotSubscriber, jitProxyClient, driftClient, userStatsMap, }: {
|
|
19
|
+
constructor({ auctionSubscriber, slotSubscriber, jitProxyClient, driftClient, userStatsMap, swiftOrderSubscriber, }: {
|
|
19
20
|
driftClient: DriftClient;
|
|
20
21
|
slotSubscriber: SlotSubscriber;
|
|
21
22
|
auctionSubscriber: AuctionSubscriber;
|
|
22
23
|
jitProxyClient: JitProxyClient;
|
|
23
24
|
userStatsMap?: UserStatsMap;
|
|
25
|
+
swiftOrderSubscriber?: SwiftOrderSubscriber;
|
|
24
26
|
});
|
|
25
27
|
createTryFill(taker: UserAccount, takerKey: PublicKey, takerStatsKey: PublicKey, order: Order, orderSignature: string): () => Promise<void>;
|
|
28
|
+
createTrySwiftFill(authorityToUse: PublicKey, signedSwiftOrderParams: SignedSwiftOrderParams, uuid: Uint8Array, taker: UserAccount, takerKey: PublicKey, takerStatsKey: PublicKey, order: Order, orderSignature: string, marketIndex: number): () => Promise<void>;
|
|
26
29
|
getAuctionAndOrderDetails(order: Order): AuctionAndOrderDetails;
|
|
27
30
|
waitForSlotOrCrossOrExpiry(targetSlot: number, order: Order, initialDetails: AuctionAndOrderDetails): Promise<{
|
|
28
31
|
slot: number;
|
|
@@ -4,12 +4,14 @@ exports.JitterSniper = void 0;
|
|
|
4
4
|
const sdk_1 = require("@drift-labs/sdk");
|
|
5
5
|
const baseJitter_1 = require("./baseJitter");
|
|
6
6
|
class JitterSniper extends baseJitter_1.BaseJitter {
|
|
7
|
-
constructor({ auctionSubscriber, slotSubscriber, jitProxyClient, driftClient, userStatsMap, }) {
|
|
7
|
+
constructor({ auctionSubscriber, slotSubscriber, jitProxyClient, driftClient, userStatsMap, swiftOrderSubscriber, }) {
|
|
8
8
|
super({
|
|
9
9
|
auctionSubscriber,
|
|
10
10
|
jitProxyClient,
|
|
11
11
|
driftClient,
|
|
12
12
|
userStatsMap,
|
|
13
|
+
swiftOrderSubscriber,
|
|
14
|
+
slotSubscriber,
|
|
13
15
|
});
|
|
14
16
|
this.slotSubscriber = slotSubscriber;
|
|
15
17
|
}
|
|
@@ -142,6 +144,139 @@ class JitterSniper extends baseJitter_1.BaseJitter {
|
|
|
142
144
|
this.deleteOnGoingAuction(orderSignature);
|
|
143
145
|
};
|
|
144
146
|
}
|
|
147
|
+
createTrySwiftFill(authorityToUse, signedSwiftOrderParams, uuid, taker, takerKey, takerStatsKey, order, orderSignature, marketIndex) {
|
|
148
|
+
return async () => {
|
|
149
|
+
const params = this.perpParams.get(order.marketIndex);
|
|
150
|
+
if (!params) {
|
|
151
|
+
this.deleteOnGoingAuction(orderSignature);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
const takerStats = await this.userStatsMap.mustGet(taker.authority.toString());
|
|
155
|
+
const referrerInfo = takerStats.getReferrerInfo();
|
|
156
|
+
const { slotsTilCross, willCross, bid, ask, auctionStartPrice, auctionEndPrice, stepSize, oraclePrice, } = this.getAuctionAndOrderDetails(order);
|
|
157
|
+
// don't increase risk if we're past max positions
|
|
158
|
+
if ((0, sdk_1.isVariant)(order.marketType, 'perp')) {
|
|
159
|
+
const currPerpPos = this.driftClient.getUser().getPerpPosition(order.marketIndex) ||
|
|
160
|
+
this.driftClient.getUser().getEmptyPosition(order.marketIndex);
|
|
161
|
+
if (currPerpPos.baseAssetAmount.lt(sdk_1.ZERO) &&
|
|
162
|
+
(0, sdk_1.isVariant)(order.direction, 'short')) {
|
|
163
|
+
if (currPerpPos.baseAssetAmount.lte(params.minPosition)) {
|
|
164
|
+
console.log(`Order would increase existing short (mkt ${(0, sdk_1.getVariant)(order.marketType)}-${order.marketIndex}) too much`);
|
|
165
|
+
this.deleteOnGoingAuction(orderSignature);
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
else if (currPerpPos.baseAssetAmount.gt(sdk_1.ZERO) &&
|
|
170
|
+
(0, sdk_1.isVariant)(order.direction, 'long')) {
|
|
171
|
+
if (currPerpPos.baseAssetAmount.gte(params.maxPosition)) {
|
|
172
|
+
console.log(`Order would increase existing long (mkt ${(0, sdk_1.getVariant)(order.marketType)}-${order.marketIndex}) too much`);
|
|
173
|
+
this.deleteOnGoingAuction(orderSignature);
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
console.log(`
|
|
179
|
+
Taker wants to ${JSON.stringify(order.direction)}, order slot is ${order.slot.toNumber()},
|
|
180
|
+
My market: ${bid}@${ask},
|
|
181
|
+
Auction: ${auctionStartPrice} -> ${auctionEndPrice}, step size ${stepSize}
|
|
182
|
+
Current slot: ${this.slotSubscriber.currentSlot}, Order slot: ${order.slot.toNumber()},
|
|
183
|
+
Will cross?: ${willCross}
|
|
184
|
+
Slots to wait: ${slotsTilCross}. Target slot = ${order.slot.toNumber() + slotsTilCross}
|
|
185
|
+
`);
|
|
186
|
+
this.waitForSlotOrCrossOrExpiry(willCross
|
|
187
|
+
? order.slot.toNumber() + slotsTilCross
|
|
188
|
+
: order.slot.toNumber() + order.auctionDuration + 1, order, {
|
|
189
|
+
slotsTilCross,
|
|
190
|
+
willCross,
|
|
191
|
+
bid,
|
|
192
|
+
ask,
|
|
193
|
+
auctionStartPrice,
|
|
194
|
+
auctionEndPrice,
|
|
195
|
+
stepSize,
|
|
196
|
+
oraclePrice,
|
|
197
|
+
}).then(async ({ slot, updatedDetails }) => {
|
|
198
|
+
var _a;
|
|
199
|
+
if (slot === -1) {
|
|
200
|
+
console.log('Auction expired without crossing');
|
|
201
|
+
this.deleteOnGoingAuction(orderSignature);
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
const params = (0, sdk_1.isVariant)(order.marketType, 'perp')
|
|
205
|
+
? this.perpParams.get(order.marketIndex)
|
|
206
|
+
: this.spotParams.get(order.marketIndex);
|
|
207
|
+
const bid = (0, sdk_1.isVariant)(params.priceType, 'oracle')
|
|
208
|
+
? (0, sdk_1.convertToNumber)(oraclePrice.price.add(params.bid), sdk_1.PRICE_PRECISION)
|
|
209
|
+
: (0, sdk_1.convertToNumber)(params.bid, sdk_1.PRICE_PRECISION);
|
|
210
|
+
const ask = (0, sdk_1.isVariant)(params.priceType, 'oracle')
|
|
211
|
+
? (0, sdk_1.convertToNumber)(oraclePrice.price.add(params.ask), sdk_1.PRICE_PRECISION)
|
|
212
|
+
: (0, sdk_1.convertToNumber)(params.ask, sdk_1.PRICE_PRECISION);
|
|
213
|
+
const auctionPrice = (0, sdk_1.convertToNumber)((0, sdk_1.getAuctionPrice)(order, slot, updatedDetails.oraclePrice.price), sdk_1.PRICE_PRECISION);
|
|
214
|
+
console.log(`
|
|
215
|
+
Expected auction price: ${auctionStartPrice + slotsTilCross * stepSize}
|
|
216
|
+
Actual auction price: ${auctionPrice}
|
|
217
|
+
-----------------
|
|
218
|
+
Looking for slot ${order.slot.toNumber() + slotsTilCross}
|
|
219
|
+
Got slot ${slot}
|
|
220
|
+
`);
|
|
221
|
+
console.log(`Trying to fill ${orderSignature} with:
|
|
222
|
+
market: ${bid}@${ask}
|
|
223
|
+
auction price: ${auctionPrice}
|
|
224
|
+
submitting" ${(0, sdk_1.convertToNumber)(params.bid, sdk_1.PRICE_PRECISION)}@${(0, sdk_1.convertToNumber)(params.ask, sdk_1.PRICE_PRECISION)}
|
|
225
|
+
`);
|
|
226
|
+
let i = 0;
|
|
227
|
+
while (i < 10) {
|
|
228
|
+
try {
|
|
229
|
+
const txParams = {
|
|
230
|
+
computeUnits: this.computeUnits,
|
|
231
|
+
computeUnitsPrice: this.computeUnitsPrice,
|
|
232
|
+
};
|
|
233
|
+
const { txSig } = await this.jitProxyClient.jitSwift({
|
|
234
|
+
takerKey,
|
|
235
|
+
takerStatsKey,
|
|
236
|
+
taker,
|
|
237
|
+
takerOrderId: order.orderId,
|
|
238
|
+
maxPosition: params.maxPosition,
|
|
239
|
+
minPosition: params.minPosition,
|
|
240
|
+
bid: params.bid,
|
|
241
|
+
ask: params.ask,
|
|
242
|
+
postOnly: (_a = params.postOnlyParams) !== null && _a !== void 0 ? _a : sdk_1.PostOnlyParams.MUST_POST_ONLY,
|
|
243
|
+
priceType: params.priceType,
|
|
244
|
+
referrerInfo,
|
|
245
|
+
subAccountId: params.subAccountId,
|
|
246
|
+
authorityToUse,
|
|
247
|
+
signedSwiftOrderParams,
|
|
248
|
+
uuid,
|
|
249
|
+
marketIndex,
|
|
250
|
+
}, txParams);
|
|
251
|
+
console.log(`Filled ${orderSignature} txSig ${txSig}`);
|
|
252
|
+
await sleep(3000);
|
|
253
|
+
this.deleteOnGoingAuction(orderSignature);
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
catch (e) {
|
|
257
|
+
console.error(`Failed to fill ${orderSignature}`);
|
|
258
|
+
if (e.message.includes('0x1770') || e.message.includes('0x1771')) {
|
|
259
|
+
console.log('Order does not cross params yet');
|
|
260
|
+
}
|
|
261
|
+
else if (e.message.includes('0x1779')) {
|
|
262
|
+
console.log('Order could not fill');
|
|
263
|
+
}
|
|
264
|
+
else if (e.message.includes('0x1793')) {
|
|
265
|
+
console.log('Oracle invalid');
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
await sleep(3000);
|
|
269
|
+
this.deleteOnGoingAuction(orderSignature);
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
await sleep(200);
|
|
274
|
+
i++;
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
this.deleteOnGoingAuction(orderSignature);
|
|
278
|
+
};
|
|
279
|
+
}
|
|
145
280
|
getAuctionAndOrderDetails(order) {
|
|
146
281
|
// Find number of slots until the order is expected to be in cross
|
|
147
282
|
const params = (0, sdk_1.isVariant)(order.marketType, 'perp')
|