@drift-labs/jit-proxy 0.10.1 → 0.10.2
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/index.d.ts +4 -0
- package/lib/index.js +20 -0
- package/lib/jitProxyClient.d.ts +46 -0
- package/lib/jitProxyClient.js +112 -0
- package/lib/jitter/baseJitter.d.ts +35 -0
- package/lib/jitter/baseJitter.js +88 -0
- package/lib/jitter/jitterShotgun.d.ts +23 -0
- package/lib/jitter/jitterShotgun.js +69 -0
- package/lib/jitter/jitterSniper.d.ts +32 -0
- package/lib/jitter/jitterSniper.js +201 -0
- package/lib/types/jit_proxy.d.ts +212 -0
- package/lib/types/jit_proxy.js +214 -0
- package/package.json +5 -1
- package/src/types/jit_proxy.ts +2 -2
package/lib/index.d.ts
ADDED
package/lib/index.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./types/jit_proxy"), exports);
|
|
18
|
+
__exportStar(require("./jitProxyClient"), exports);
|
|
19
|
+
__exportStar(require("./jitter/jitterSniper"), exports);
|
|
20
|
+
__exportStar(require("./jitter/jitterShotgun"), exports);
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/// <reference types="bn.js" />
|
|
2
|
+
import { BN, DriftClient, MarketType, PostOnlyParams, ReferrerInfo, TxParams, UserAccount } from '@drift-labs/sdk';
|
|
3
|
+
import { PublicKey, TransactionInstruction } from '@solana/web3.js';
|
|
4
|
+
import { TxSigAndSlot } from '@drift-labs/sdk/lib/tx/types';
|
|
5
|
+
export declare type JitIxParams = {
|
|
6
|
+
takerKey: PublicKey;
|
|
7
|
+
takerStatsKey: PublicKey;
|
|
8
|
+
taker: UserAccount;
|
|
9
|
+
takerOrderId: number;
|
|
10
|
+
maxPosition: BN;
|
|
11
|
+
minPosition: BN;
|
|
12
|
+
bid: BN;
|
|
13
|
+
ask: BN;
|
|
14
|
+
postOnly: PostOnlyParams | null;
|
|
15
|
+
priceType?: PriceType;
|
|
16
|
+
referrerInfo?: ReferrerInfo;
|
|
17
|
+
subAccountId?: number;
|
|
18
|
+
};
|
|
19
|
+
export declare class PriceType {
|
|
20
|
+
static readonly LIMIT: {
|
|
21
|
+
limit: {};
|
|
22
|
+
};
|
|
23
|
+
static readonly ORACLE: {
|
|
24
|
+
oracle: {};
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export declare type OrderConstraint = {
|
|
28
|
+
maxPosition: BN;
|
|
29
|
+
minPosition: BN;
|
|
30
|
+
marketIndex: number;
|
|
31
|
+
marketType: MarketType;
|
|
32
|
+
};
|
|
33
|
+
export declare class JitProxyClient {
|
|
34
|
+
private driftClient;
|
|
35
|
+
private program;
|
|
36
|
+
constructor({ driftClient, programId, }: {
|
|
37
|
+
driftClient: DriftClient;
|
|
38
|
+
programId: PublicKey;
|
|
39
|
+
});
|
|
40
|
+
jit(params: JitIxParams, txParams?: TxParams): Promise<TxSigAndSlot>;
|
|
41
|
+
getJitIx({ takerKey, takerStatsKey, taker, takerOrderId, maxPosition, minPosition, bid, ask, postOnly, priceType, referrerInfo, subAccountId, }: JitIxParams): Promise<TransactionInstruction>;
|
|
42
|
+
getCheckOrderConstraintIx({ subAccountId, orderConstraints, }: {
|
|
43
|
+
subAccountId: number;
|
|
44
|
+
orderConstraints: OrderConstraint[];
|
|
45
|
+
}): Promise<TransactionInstruction>;
|
|
46
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.JitProxyClient = exports.PriceType = void 0;
|
|
4
|
+
const sdk_1 = require("@drift-labs/sdk");
|
|
5
|
+
const jit_proxy_1 = require("./types/jit_proxy");
|
|
6
|
+
const anchor_1 = require("@coral-xyz/anchor");
|
|
7
|
+
class PriceType {
|
|
8
|
+
}
|
|
9
|
+
exports.PriceType = PriceType;
|
|
10
|
+
PriceType.LIMIT = { limit: {} };
|
|
11
|
+
PriceType.ORACLE = { oracle: {} };
|
|
12
|
+
class JitProxyClient {
|
|
13
|
+
constructor({ driftClient, programId, }) {
|
|
14
|
+
this.driftClient = driftClient;
|
|
15
|
+
this.program = new anchor_1.Program(jit_proxy_1.IDL, programId, driftClient.provider);
|
|
16
|
+
}
|
|
17
|
+
async jit(params, txParams) {
|
|
18
|
+
const ix = await this.getJitIx(params);
|
|
19
|
+
const tx = await this.driftClient.buildTransaction([ix], txParams);
|
|
20
|
+
return await this.driftClient.sendTransaction(tx);
|
|
21
|
+
}
|
|
22
|
+
async getJitIx({ takerKey, takerStatsKey, taker, takerOrderId, maxPosition, minPosition, bid, ask, postOnly = null, priceType = PriceType.LIMIT, referrerInfo, subAccountId, }) {
|
|
23
|
+
subAccountId =
|
|
24
|
+
subAccountId !== undefined
|
|
25
|
+
? subAccountId
|
|
26
|
+
: this.driftClient.activeSubAccountId;
|
|
27
|
+
const order = taker.orders.find((order) => order.orderId === takerOrderId);
|
|
28
|
+
const remainingAccounts = this.driftClient.getRemainingAccounts({
|
|
29
|
+
userAccounts: [taker, this.driftClient.getUserAccount(subAccountId)],
|
|
30
|
+
writableSpotMarketIndexes: (0, sdk_1.isVariant)(order.marketType, 'spot')
|
|
31
|
+
? [order.marketIndex, sdk_1.QUOTE_SPOT_MARKET_INDEX]
|
|
32
|
+
: [],
|
|
33
|
+
writablePerpMarketIndexes: (0, sdk_1.isVariant)(order.marketType, 'perp')
|
|
34
|
+
? [order.marketIndex]
|
|
35
|
+
: [],
|
|
36
|
+
});
|
|
37
|
+
if (referrerInfo) {
|
|
38
|
+
remainingAccounts.push({
|
|
39
|
+
pubkey: referrerInfo.referrer,
|
|
40
|
+
isWritable: true,
|
|
41
|
+
isSigner: false,
|
|
42
|
+
});
|
|
43
|
+
remainingAccounts.push({
|
|
44
|
+
pubkey: referrerInfo.referrerStats,
|
|
45
|
+
isWritable: true,
|
|
46
|
+
isSigner: false,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
if ((0, sdk_1.isVariant)(order.marketType, 'spot')) {
|
|
50
|
+
remainingAccounts.push({
|
|
51
|
+
pubkey: this.driftClient.getSpotMarketAccount(order.marketIndex).vault,
|
|
52
|
+
isWritable: false,
|
|
53
|
+
isSigner: false,
|
|
54
|
+
});
|
|
55
|
+
remainingAccounts.push({
|
|
56
|
+
pubkey: this.driftClient.getQuoteSpotMarketAccount().vault,
|
|
57
|
+
isWritable: false,
|
|
58
|
+
isSigner: false,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
const jitParams = {
|
|
62
|
+
takerOrderId,
|
|
63
|
+
maxPosition,
|
|
64
|
+
minPosition,
|
|
65
|
+
bid,
|
|
66
|
+
ask,
|
|
67
|
+
postOnly,
|
|
68
|
+
priceType,
|
|
69
|
+
};
|
|
70
|
+
return this.program.methods
|
|
71
|
+
.jit(jitParams)
|
|
72
|
+
.accounts({
|
|
73
|
+
taker: takerKey,
|
|
74
|
+
takerStats: takerStatsKey,
|
|
75
|
+
state: await this.driftClient.getStatePublicKey(),
|
|
76
|
+
user: await this.driftClient.getUserAccountPublicKey(subAccountId),
|
|
77
|
+
userStats: this.driftClient.getUserStatsAccountPublicKey(),
|
|
78
|
+
driftProgram: this.driftClient.program.programId,
|
|
79
|
+
})
|
|
80
|
+
.remainingAccounts(remainingAccounts)
|
|
81
|
+
.instruction();
|
|
82
|
+
}
|
|
83
|
+
async getCheckOrderConstraintIx({ subAccountId, orderConstraints, }) {
|
|
84
|
+
subAccountId =
|
|
85
|
+
subAccountId !== undefined
|
|
86
|
+
? subAccountId
|
|
87
|
+
: this.driftClient.activeSubAccountId;
|
|
88
|
+
const readablePerpMarketIndex = [];
|
|
89
|
+
const readableSpotMarketIndexes = [];
|
|
90
|
+
for (const orderConstraint of orderConstraints) {
|
|
91
|
+
if ((0, sdk_1.isVariant)(orderConstraint.marketType, 'perp')) {
|
|
92
|
+
readablePerpMarketIndex.push(orderConstraint.marketIndex);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
readableSpotMarketIndexes.push(orderConstraint.marketIndex);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
const remainingAccounts = this.driftClient.getRemainingAccounts({
|
|
99
|
+
userAccounts: [this.driftClient.getUserAccount(subAccountId)],
|
|
100
|
+
readableSpotMarketIndexes,
|
|
101
|
+
readablePerpMarketIndex,
|
|
102
|
+
});
|
|
103
|
+
return this.program.methods
|
|
104
|
+
.checkOrderConstraints(orderConstraints)
|
|
105
|
+
.accounts({
|
|
106
|
+
user: await this.driftClient.getUserAccountPublicKey(subAccountId),
|
|
107
|
+
})
|
|
108
|
+
.remainingAccounts(remainingAccounts)
|
|
109
|
+
.instruction();
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
exports.JitProxyClient = JitProxyClient;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/// <reference types="bn.js" />
|
|
2
|
+
import { JitProxyClient, PriceType } from '../jitProxyClient';
|
|
3
|
+
import { PublicKey } from '@solana/web3.js';
|
|
4
|
+
import { AuctionSubscriber, BN, DriftClient, Order, UserAccount, UserStatsMap } from '@drift-labs/sdk';
|
|
5
|
+
export declare type UserFilter = (userAccount: UserAccount, userKey: string, order: Order) => boolean;
|
|
6
|
+
export declare type JitParams = {
|
|
7
|
+
bid: BN;
|
|
8
|
+
ask: BN;
|
|
9
|
+
minPosition: BN;
|
|
10
|
+
maxPosition: any;
|
|
11
|
+
priceType: PriceType;
|
|
12
|
+
subAccountId?: number;
|
|
13
|
+
};
|
|
14
|
+
export declare abstract class BaseJitter {
|
|
15
|
+
auctionSubscriber: AuctionSubscriber;
|
|
16
|
+
driftClient: DriftClient;
|
|
17
|
+
jitProxyClient: JitProxyClient;
|
|
18
|
+
userStatsMap: UserStatsMap;
|
|
19
|
+
perpParams: Map<number, JitParams>;
|
|
20
|
+
spotParams: Map<number, JitParams>;
|
|
21
|
+
onGoingAuctions: Map<string, Promise<void>>;
|
|
22
|
+
userFilter: UserFilter;
|
|
23
|
+
constructor({ auctionSubscriber, jitProxyClient, driftClient, userStatsMap, }: {
|
|
24
|
+
driftClient: DriftClient;
|
|
25
|
+
auctionSubscriber: AuctionSubscriber;
|
|
26
|
+
jitProxyClient: JitProxyClient;
|
|
27
|
+
userStatsMap?: UserStatsMap;
|
|
28
|
+
});
|
|
29
|
+
subscribe(): Promise<void>;
|
|
30
|
+
createTryFill(taker: UserAccount, takerKey: PublicKey, takerStatsKey: PublicKey, order: Order, orderSignature: string): () => Promise<void>;
|
|
31
|
+
getOrderSignatures(takerKey: string, orderId: number): string;
|
|
32
|
+
updatePerpParams(marketIndex: number, params: JitParams): void;
|
|
33
|
+
updateSpotParams(marketIndex: number, params: JitParams): void;
|
|
34
|
+
setUserFilter(userFilter: UserFilter | undefined): void;
|
|
35
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BaseJitter = void 0;
|
|
4
|
+
const sdk_1 = require("@drift-labs/sdk");
|
|
5
|
+
class BaseJitter {
|
|
6
|
+
constructor({ auctionSubscriber, jitProxyClient, driftClient, userStatsMap, }) {
|
|
7
|
+
this.perpParams = new Map();
|
|
8
|
+
this.spotParams = new Map();
|
|
9
|
+
this.onGoingAuctions = new Map();
|
|
10
|
+
this.auctionSubscriber = auctionSubscriber;
|
|
11
|
+
this.driftClient = driftClient;
|
|
12
|
+
this.jitProxyClient = jitProxyClient;
|
|
13
|
+
this.userStatsMap =
|
|
14
|
+
userStatsMap ||
|
|
15
|
+
new sdk_1.UserStatsMap(this.driftClient, {
|
|
16
|
+
type: 'polling',
|
|
17
|
+
accountLoader: new sdk_1.BulkAccountLoader(this.driftClient.connection, 'confirmed', 0),
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
async subscribe() {
|
|
21
|
+
await this.driftClient.subscribe();
|
|
22
|
+
await this.userStatsMap.subscribe();
|
|
23
|
+
await this.auctionSubscriber.subscribe();
|
|
24
|
+
this.auctionSubscriber.eventEmitter.on('onAccountUpdate', async (taker, takerKey, slot) => {
|
|
25
|
+
const takerKeyString = takerKey.toBase58();
|
|
26
|
+
const takerStatsKey = (0, sdk_1.getUserStatsAccountPublicKey)(this.driftClient.program.programId, taker.authority);
|
|
27
|
+
for (const order of taker.orders) {
|
|
28
|
+
if (!(0, sdk_1.isVariant)(order.status, 'open')) {
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
if (!(0, sdk_1.hasAuctionPrice)(order, slot)) {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (this.userFilter) {
|
|
35
|
+
if (this.userFilter(taker, takerKeyString, order)) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const orderSignature = this.getOrderSignatures(takerKeyString, order.orderId);
|
|
40
|
+
if (this.onGoingAuctions.has(orderSignature)) {
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
if ((0, sdk_1.isVariant)(order.marketType, 'perp')) {
|
|
44
|
+
if (!this.perpParams.has(order.marketIndex)) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const perpMarketAccount = this.driftClient.getPerpMarketAccount(order.marketIndex);
|
|
48
|
+
if (order.baseAssetAmount
|
|
49
|
+
.sub(order.baseAssetAmountFilled)
|
|
50
|
+
.lte(perpMarketAccount.amm.minOrderSize)) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const promise = this.createTryFill(taker, takerKey, takerStatsKey, order, orderSignature).bind(this)();
|
|
54
|
+
this.onGoingAuctions.set(orderSignature, promise);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
if (!this.spotParams.has(order.marketIndex)) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
const spotMarketAccount = this.driftClient.getSpotMarketAccount(order.marketIndex);
|
|
61
|
+
if (order.baseAssetAmount
|
|
62
|
+
.sub(order.baseAssetAmountFilled)
|
|
63
|
+
.lte(spotMarketAccount.minOrderSize)) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const promise = this.createTryFill(taker, takerKey, takerStatsKey, order, orderSignature).bind(this)();
|
|
67
|
+
this.onGoingAuctions.set(orderSignature, promise);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
createTryFill(taker, takerKey, takerStatsKey, order, orderSignature) {
|
|
73
|
+
throw new Error('Not implemented');
|
|
74
|
+
}
|
|
75
|
+
getOrderSignatures(takerKey, orderId) {
|
|
76
|
+
return `${takerKey}-${orderId}`;
|
|
77
|
+
}
|
|
78
|
+
updatePerpParams(marketIndex, params) {
|
|
79
|
+
this.perpParams.set(marketIndex, params);
|
|
80
|
+
}
|
|
81
|
+
updateSpotParams(marketIndex, params) {
|
|
82
|
+
this.spotParams.set(marketIndex, params);
|
|
83
|
+
}
|
|
84
|
+
setUserFilter(userFilter) {
|
|
85
|
+
this.userFilter = userFilter;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
exports.BaseJitter = BaseJitter;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/// <reference types="bn.js" />
|
|
2
|
+
import { JitProxyClient, PriceType } from '../jitProxyClient';
|
|
3
|
+
import { PublicKey } from '@solana/web3.js';
|
|
4
|
+
import { AuctionSubscriber, BN, DriftClient, Order, UserAccount, UserStatsMap } from '@drift-labs/sdk';
|
|
5
|
+
import { BaseJitter } from './baseJitter';
|
|
6
|
+
export declare type UserFilter = (userAccount: UserAccount, userKey: string, order: Order) => boolean;
|
|
7
|
+
export declare type JitParams = {
|
|
8
|
+
bid: BN;
|
|
9
|
+
ask: BN;
|
|
10
|
+
minPosition: BN;
|
|
11
|
+
maxPosition: any;
|
|
12
|
+
priceType: PriceType;
|
|
13
|
+
subAccountId?: number;
|
|
14
|
+
};
|
|
15
|
+
export declare class JitterShotgun extends BaseJitter {
|
|
16
|
+
constructor({ auctionSubscriber, jitProxyClient, driftClient, userStatsMap, }: {
|
|
17
|
+
driftClient: DriftClient;
|
|
18
|
+
auctionSubscriber: AuctionSubscriber;
|
|
19
|
+
jitProxyClient: JitProxyClient;
|
|
20
|
+
userStatsMap?: UserStatsMap;
|
|
21
|
+
});
|
|
22
|
+
createTryFill(taker: UserAccount, takerKey: PublicKey, takerStatsKey: PublicKey, order: Order, orderSignature: string): () => Promise<void>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.JitterShotgun = void 0;
|
|
4
|
+
const baseJitter_1 = require("./baseJitter");
|
|
5
|
+
class JitterShotgun extends baseJitter_1.BaseJitter {
|
|
6
|
+
constructor({ auctionSubscriber, jitProxyClient, driftClient, userStatsMap, }) {
|
|
7
|
+
super({
|
|
8
|
+
auctionSubscriber,
|
|
9
|
+
jitProxyClient,
|
|
10
|
+
driftClient,
|
|
11
|
+
userStatsMap,
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
createTryFill(taker, takerKey, takerStatsKey, order, orderSignature) {
|
|
15
|
+
return async () => {
|
|
16
|
+
let i = 0;
|
|
17
|
+
while (i < 10) {
|
|
18
|
+
const params = this.perpParams.get(order.marketIndex);
|
|
19
|
+
if (!params) {
|
|
20
|
+
this.onGoingAuctions.delete(orderSignature);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const takerStats = await this.userStatsMap.mustGet(taker.authority.toString());
|
|
24
|
+
const referrerInfo = takerStats.getReferrerInfo();
|
|
25
|
+
console.log(`Trying to fill ${orderSignature}`);
|
|
26
|
+
try {
|
|
27
|
+
const { txSig } = await this.jitProxyClient.jit({
|
|
28
|
+
takerKey,
|
|
29
|
+
takerStatsKey,
|
|
30
|
+
taker,
|
|
31
|
+
takerOrderId: order.orderId,
|
|
32
|
+
maxPosition: params.maxPosition,
|
|
33
|
+
minPosition: params.minPosition,
|
|
34
|
+
bid: params.bid,
|
|
35
|
+
ask: params.ask,
|
|
36
|
+
postOnly: null,
|
|
37
|
+
priceType: params.priceType,
|
|
38
|
+
referrerInfo,
|
|
39
|
+
subAccountId: params.subAccountId,
|
|
40
|
+
});
|
|
41
|
+
console.log(`Filled ${orderSignature} txSig ${txSig}`);
|
|
42
|
+
await sleep(10000);
|
|
43
|
+
this.onGoingAuctions.delete(orderSignature);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
catch (e) {
|
|
47
|
+
console.error(`Failed to fill ${orderSignature}`);
|
|
48
|
+
if (e.message.includes('0x1770') || e.message.includes('0x1771')) {
|
|
49
|
+
console.log('Order does not cross params yet, retrying');
|
|
50
|
+
}
|
|
51
|
+
else if (e.message.includes('0x1793')) {
|
|
52
|
+
console.log('Oracle invalid, retrying');
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
await sleep(10000);
|
|
56
|
+
this.onGoingAuctions.delete(orderSignature);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
i++;
|
|
61
|
+
}
|
|
62
|
+
this.onGoingAuctions.delete(orderSignature);
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
exports.JitterShotgun = JitterShotgun;
|
|
67
|
+
function sleep(ms) {
|
|
68
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
69
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { JitProxyClient } from '../jitProxyClient';
|
|
2
|
+
import { PublicKey } from '@solana/web3.js';
|
|
3
|
+
import { AuctionSubscriber, DriftClient, OraclePriceData, Order, SlotSubscriber, UserAccount, UserStatsMap } from '@drift-labs/sdk';
|
|
4
|
+
import { BaseJitter } from './baseJitter';
|
|
5
|
+
declare type AuctionAndOrderDetails = {
|
|
6
|
+
slotsTilCross: number;
|
|
7
|
+
willCross: boolean;
|
|
8
|
+
bid: number;
|
|
9
|
+
ask: number;
|
|
10
|
+
auctionStartPrice: number;
|
|
11
|
+
auctionEndPrice: number;
|
|
12
|
+
stepSize: number;
|
|
13
|
+
oraclePrice: OraclePriceData;
|
|
14
|
+
};
|
|
15
|
+
export declare class JitterSniper extends BaseJitter {
|
|
16
|
+
slotSubscriber: SlotSubscriber;
|
|
17
|
+
userStatsMap: UserStatsMap;
|
|
18
|
+
constructor({ auctionSubscriber, slotSubscriber, jitProxyClient, driftClient, userStatsMap, }: {
|
|
19
|
+
driftClient: DriftClient;
|
|
20
|
+
slotSubscriber: SlotSubscriber;
|
|
21
|
+
auctionSubscriber: AuctionSubscriber;
|
|
22
|
+
jitProxyClient: JitProxyClient;
|
|
23
|
+
userStatsMap?: UserStatsMap;
|
|
24
|
+
});
|
|
25
|
+
createTryFill(taker: UserAccount, takerKey: PublicKey, takerStatsKey: PublicKey, order: Order, orderSignature: string): () => Promise<void>;
|
|
26
|
+
getAuctionAndOrderDetails(order: Order): AuctionAndOrderDetails;
|
|
27
|
+
waitForSlotOrCrossOrExpiry(targetSlot: number, order: Order, initialDetails: AuctionAndOrderDetails): Promise<{
|
|
28
|
+
slot: number;
|
|
29
|
+
updatedDetails: AuctionAndOrderDetails;
|
|
30
|
+
}>;
|
|
31
|
+
}
|
|
32
|
+
export {};
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.JitterSniper = void 0;
|
|
4
|
+
const sdk_1 = require("@drift-labs/sdk");
|
|
5
|
+
const baseJitter_1 = require("./baseJitter");
|
|
6
|
+
class JitterSniper extends baseJitter_1.BaseJitter {
|
|
7
|
+
constructor({ auctionSubscriber, slotSubscriber, jitProxyClient, driftClient, userStatsMap, }) {
|
|
8
|
+
super({
|
|
9
|
+
auctionSubscriber,
|
|
10
|
+
jitProxyClient,
|
|
11
|
+
driftClient,
|
|
12
|
+
userStatsMap,
|
|
13
|
+
});
|
|
14
|
+
this.slotSubscriber = slotSubscriber;
|
|
15
|
+
}
|
|
16
|
+
createTryFill(taker, takerKey, takerStatsKey, order, orderSignature) {
|
|
17
|
+
return async () => {
|
|
18
|
+
const params = this.perpParams.get(order.marketIndex);
|
|
19
|
+
if (!params) {
|
|
20
|
+
this.onGoingAuctions.delete(orderSignature);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const takerStats = await this.userStatsMap.mustGet(taker.authority.toString());
|
|
24
|
+
const referrerInfo = takerStats.getReferrerInfo();
|
|
25
|
+
const { slotsTilCross, willCross, bid, ask, auctionStartPrice, auctionEndPrice, stepSize, oraclePrice, } = this.getAuctionAndOrderDetails(order);
|
|
26
|
+
console.log(`
|
|
27
|
+
Taker wants to ${JSON.stringify(order.direction)}, order slot is ${order.slot.toNumber()},
|
|
28
|
+
My market: ${bid}@${ask},
|
|
29
|
+
Auction: ${auctionStartPrice} -> ${auctionEndPrice}, step size ${stepSize}
|
|
30
|
+
Current slot: ${this.slotSubscriber.currentSlot}, Order slot: ${order.slot.toNumber()},
|
|
31
|
+
Will cross?: ${willCross}
|
|
32
|
+
Slots to wait: ${slotsTilCross}. Target slot = ${order.slot.toNumber() + slotsTilCross}
|
|
33
|
+
`);
|
|
34
|
+
this.waitForSlotOrCrossOrExpiry(willCross
|
|
35
|
+
? order.slot.toNumber() + slotsTilCross
|
|
36
|
+
: order.slot.toNumber() + order.auctionDuration + 1, order, {
|
|
37
|
+
slotsTilCross,
|
|
38
|
+
willCross,
|
|
39
|
+
bid,
|
|
40
|
+
ask,
|
|
41
|
+
auctionStartPrice,
|
|
42
|
+
auctionEndPrice,
|
|
43
|
+
stepSize,
|
|
44
|
+
oraclePrice,
|
|
45
|
+
}).then(async ({ slot, updatedDetails }) => {
|
|
46
|
+
if (slot === -1) {
|
|
47
|
+
console.log('Auction expired without crossing');
|
|
48
|
+
this.onGoingAuctions.delete(orderSignature);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const params = (0, sdk_1.isVariant)(order.marketType, 'perp')
|
|
52
|
+
? this.perpParams.get(order.marketIndex)
|
|
53
|
+
: this.spotParams.get(order.marketIndex);
|
|
54
|
+
const bid = (0, sdk_1.isVariant)(params.priceType, 'oracle')
|
|
55
|
+
? (0, sdk_1.convertToNumber)(oraclePrice.price.add(params.bid), sdk_1.PRICE_PRECISION)
|
|
56
|
+
: (0, sdk_1.convertToNumber)(params.bid, sdk_1.PRICE_PRECISION);
|
|
57
|
+
const ask = (0, sdk_1.isVariant)(params.priceType, 'oracle')
|
|
58
|
+
? (0, sdk_1.convertToNumber)(oraclePrice.price.add(params.ask), sdk_1.PRICE_PRECISION)
|
|
59
|
+
: (0, sdk_1.convertToNumber)(params.ask, sdk_1.PRICE_PRECISION);
|
|
60
|
+
const auctionPrice = (0, sdk_1.convertToNumber)((0, sdk_1.getAuctionPrice)(order, slot, updatedDetails.oraclePrice.price), sdk_1.PRICE_PRECISION);
|
|
61
|
+
console.log(`
|
|
62
|
+
Expected auction price: ${auctionStartPrice + slotsTilCross * stepSize}
|
|
63
|
+
Actual auction price: ${auctionPrice}
|
|
64
|
+
-----------------
|
|
65
|
+
Looking for slot ${order.slot.toNumber() + slotsTilCross}
|
|
66
|
+
Got slot ${slot}
|
|
67
|
+
`);
|
|
68
|
+
console.log(`Trying to fill ${orderSignature} with:
|
|
69
|
+
market: ${bid}@${ask}
|
|
70
|
+
auction price: ${auctionPrice}
|
|
71
|
+
submitting" ${(0, sdk_1.convertToNumber)(params.bid, sdk_1.PRICE_PRECISION)}@${(0, sdk_1.convertToNumber)(params.ask, sdk_1.PRICE_PRECISION)}
|
|
72
|
+
`);
|
|
73
|
+
let i = 0;
|
|
74
|
+
while (i < 3) {
|
|
75
|
+
try {
|
|
76
|
+
const { txSig } = await this.jitProxyClient.jit({
|
|
77
|
+
takerKey,
|
|
78
|
+
takerStatsKey,
|
|
79
|
+
taker,
|
|
80
|
+
takerOrderId: order.orderId,
|
|
81
|
+
maxPosition: params.maxPosition,
|
|
82
|
+
minPosition: params.minPosition,
|
|
83
|
+
bid: params.bid,
|
|
84
|
+
ask: params.ask,
|
|
85
|
+
postOnly: null,
|
|
86
|
+
priceType: params.priceType,
|
|
87
|
+
referrerInfo,
|
|
88
|
+
subAccountId: params.subAccountId,
|
|
89
|
+
});
|
|
90
|
+
console.log(`Filled ${orderSignature} txSig ${txSig}`);
|
|
91
|
+
await sleep(3000);
|
|
92
|
+
this.onGoingAuctions.delete(orderSignature);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
catch (e) {
|
|
96
|
+
console.error(`Failed to fill ${orderSignature}`);
|
|
97
|
+
if (e.message.includes('0x1770') || e.message.includes('0x1771')) {
|
|
98
|
+
console.log('Order does not cross params yet');
|
|
99
|
+
}
|
|
100
|
+
else if (e.message.includes('0x1793')) {
|
|
101
|
+
console.log('Oracle invalid');
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
await sleep(3000);
|
|
105
|
+
this.onGoingAuctions.delete(orderSignature);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
await sleep(50);
|
|
110
|
+
i++;
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
this.onGoingAuctions.delete(orderSignature);
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
getAuctionAndOrderDetails(order) {
|
|
117
|
+
// Find number of slots until the order is expected to be in cross
|
|
118
|
+
const params = (0, sdk_1.isVariant)(order.marketType, 'perp')
|
|
119
|
+
? this.perpParams.get(order.marketIndex)
|
|
120
|
+
: this.spotParams.get(order.marketIndex);
|
|
121
|
+
const oraclePrice = (0, sdk_1.isVariant)(order.marketType, 'perp')
|
|
122
|
+
? this.driftClient.getOracleDataForPerpMarket(order.marketIndex)
|
|
123
|
+
: this.driftClient.getOracleDataForSpotMarket(order.marketIndex);
|
|
124
|
+
const makerOrderDir = (0, sdk_1.isVariant)(order.direction, 'long') ? 'sell' : 'buy';
|
|
125
|
+
const auctionStartPrice = (0, sdk_1.convertToNumber)((0, sdk_1.isVariant)(order.orderType, 'oracle')
|
|
126
|
+
? (0, sdk_1.getAuctionPriceForOracleOffsetAuction)(order, order.slot.toNumber(), oraclePrice.price)
|
|
127
|
+
: order.auctionStartPrice, sdk_1.PRICE_PRECISION);
|
|
128
|
+
const auctionEndPrice = (0, sdk_1.convertToNumber)((0, sdk_1.isVariant)(order.orderType, 'oracle')
|
|
129
|
+
? (0, sdk_1.getAuctionPriceForOracleOffsetAuction)(order, order.slot.toNumber() + order.auctionDuration - 1, oraclePrice.price)
|
|
130
|
+
: order.auctionEndPrice, sdk_1.PRICE_PRECISION);
|
|
131
|
+
const bid = (0, sdk_1.isVariant)(params.priceType, 'oracle')
|
|
132
|
+
? (0, sdk_1.convertToNumber)(oraclePrice.price.add(params.bid), sdk_1.PRICE_PRECISION)
|
|
133
|
+
: (0, sdk_1.convertToNumber)(params.bid, sdk_1.PRICE_PRECISION);
|
|
134
|
+
const ask = (0, sdk_1.isVariant)(params.priceType, 'oracle')
|
|
135
|
+
? (0, sdk_1.convertToNumber)(oraclePrice.price.add(params.ask), sdk_1.PRICE_PRECISION)
|
|
136
|
+
: (0, sdk_1.convertToNumber)(params.ask, sdk_1.PRICE_PRECISION);
|
|
137
|
+
let slotsTilCross = 0;
|
|
138
|
+
let willCross = false;
|
|
139
|
+
const stepSize = (auctionEndPrice - auctionStartPrice) / (order.auctionDuration - 1);
|
|
140
|
+
while (slotsTilCross < order.auctionDuration) {
|
|
141
|
+
if (makerOrderDir === 'buy') {
|
|
142
|
+
if ((0, sdk_1.convertToNumber)((0, sdk_1.getAuctionPrice)(order, order.slot.toNumber() + slotsTilCross, oraclePrice.price), sdk_1.PRICE_PRECISION) <= bid) {
|
|
143
|
+
willCross = true;
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
if ((0, sdk_1.convertToNumber)((0, sdk_1.getAuctionPrice)(order, order.slot.toNumber() + slotsTilCross, oraclePrice.price), sdk_1.PRICE_PRECISION) >= ask) {
|
|
149
|
+
willCross = true;
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
slotsTilCross++;
|
|
154
|
+
}
|
|
155
|
+
return {
|
|
156
|
+
slotsTilCross,
|
|
157
|
+
willCross,
|
|
158
|
+
bid,
|
|
159
|
+
ask,
|
|
160
|
+
auctionStartPrice,
|
|
161
|
+
auctionEndPrice,
|
|
162
|
+
stepSize,
|
|
163
|
+
oraclePrice,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
async waitForSlotOrCrossOrExpiry(targetSlot, order, initialDetails) {
|
|
167
|
+
const auctionEndSlot = order.auctionDuration + order.slot.toNumber();
|
|
168
|
+
let currentDetails = initialDetails;
|
|
169
|
+
let willCross = initialDetails.willCross;
|
|
170
|
+
if (this.slotSubscriber.currentSlot > auctionEndSlot) {
|
|
171
|
+
return new Promise((resolve) => resolve({ slot: -1, updatedDetails: currentDetails }));
|
|
172
|
+
}
|
|
173
|
+
return new Promise((resolve) => {
|
|
174
|
+
// Immediately return if we are past target slot
|
|
175
|
+
const slotListener = (slot) => {
|
|
176
|
+
if (slot >= targetSlot && willCross) {
|
|
177
|
+
resolve({ slot, updatedDetails: currentDetails });
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
// Otherwise listen for new slots in case we hit the target slot and we're gonna cross
|
|
181
|
+
this.slotSubscriber.eventEmitter.once('newSlot', slotListener);
|
|
182
|
+
// Update target slot as the bid/ask and the oracle changes
|
|
183
|
+
const intervalId = setInterval(async () => {
|
|
184
|
+
if (this.slotSubscriber.currentSlot >= auctionEndSlot) {
|
|
185
|
+
this.slotSubscriber.eventEmitter.removeListener('newSlot', slotListener);
|
|
186
|
+
clearInterval(intervalId);
|
|
187
|
+
resolve({ slot: -1, updatedDetails: currentDetails });
|
|
188
|
+
}
|
|
189
|
+
currentDetails = this.getAuctionAndOrderDetails(order);
|
|
190
|
+
willCross = currentDetails.willCross;
|
|
191
|
+
if (willCross) {
|
|
192
|
+
targetSlot = order.slot.toNumber() + currentDetails.slotsTilCross;
|
|
193
|
+
}
|
|
194
|
+
}, 50);
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
exports.JitterSniper = JitterSniper;
|
|
199
|
+
function sleep(ms) {
|
|
200
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
201
|
+
}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
export declare type JitProxy = {
|
|
2
|
+
version: '0.10.2';
|
|
3
|
+
name: 'jit_proxy';
|
|
4
|
+
instructions: [
|
|
5
|
+
{
|
|
6
|
+
name: 'jit';
|
|
7
|
+
accounts: [
|
|
8
|
+
{
|
|
9
|
+
name: 'state';
|
|
10
|
+
isMut: false;
|
|
11
|
+
isSigner: false;
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
name: 'user';
|
|
15
|
+
isMut: true;
|
|
16
|
+
isSigner: false;
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
name: 'userStats';
|
|
20
|
+
isMut: true;
|
|
21
|
+
isSigner: false;
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: 'taker';
|
|
25
|
+
isMut: true;
|
|
26
|
+
isSigner: false;
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
name: 'takerStats';
|
|
30
|
+
isMut: true;
|
|
31
|
+
isSigner: false;
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: 'authority';
|
|
35
|
+
isMut: false;
|
|
36
|
+
isSigner: true;
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: 'driftProgram';
|
|
40
|
+
isMut: false;
|
|
41
|
+
isSigner: false;
|
|
42
|
+
}
|
|
43
|
+
];
|
|
44
|
+
args: [
|
|
45
|
+
{
|
|
46
|
+
name: 'params';
|
|
47
|
+
type: {
|
|
48
|
+
defined: 'JitParams';
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
];
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: 'checkOrderConstraints';
|
|
55
|
+
accounts: [
|
|
56
|
+
{
|
|
57
|
+
name: 'user';
|
|
58
|
+
isMut: false;
|
|
59
|
+
isSigner: false;
|
|
60
|
+
}
|
|
61
|
+
];
|
|
62
|
+
args: [
|
|
63
|
+
{
|
|
64
|
+
name: 'constraints';
|
|
65
|
+
type: {
|
|
66
|
+
vec: {
|
|
67
|
+
defined: 'OrderConstraint';
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
];
|
|
72
|
+
}
|
|
73
|
+
];
|
|
74
|
+
types: [
|
|
75
|
+
{
|
|
76
|
+
name: 'JitParams';
|
|
77
|
+
type: {
|
|
78
|
+
kind: 'struct';
|
|
79
|
+
fields: [
|
|
80
|
+
{
|
|
81
|
+
name: 'takerOrderId';
|
|
82
|
+
type: 'u32';
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
name: 'maxPosition';
|
|
86
|
+
type: 'i64';
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
name: 'minPosition';
|
|
90
|
+
type: 'i64';
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
name: 'bid';
|
|
94
|
+
type: 'i64';
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
name: 'ask';
|
|
98
|
+
type: 'i64';
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
name: 'priceType';
|
|
102
|
+
type: {
|
|
103
|
+
defined: 'PriceType';
|
|
104
|
+
};
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
name: 'postOnly';
|
|
108
|
+
type: {
|
|
109
|
+
option: {
|
|
110
|
+
defined: 'PostOnlyParam';
|
|
111
|
+
};
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
];
|
|
115
|
+
};
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
name: 'OrderConstraint';
|
|
119
|
+
type: {
|
|
120
|
+
kind: 'struct';
|
|
121
|
+
fields: [
|
|
122
|
+
{
|
|
123
|
+
name: 'maxPosition';
|
|
124
|
+
type: 'i64';
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
name: 'minPosition';
|
|
128
|
+
type: 'i64';
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
name: 'marketIndex';
|
|
132
|
+
type: 'u16';
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
name: 'marketType';
|
|
136
|
+
type: {
|
|
137
|
+
defined: 'MarketType';
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
];
|
|
141
|
+
};
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
name: 'PostOnlyParam';
|
|
145
|
+
type: {
|
|
146
|
+
kind: 'enum';
|
|
147
|
+
variants: [
|
|
148
|
+
{
|
|
149
|
+
name: 'None';
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
name: 'MustPostOnly';
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
name: 'TryPostOnly';
|
|
156
|
+
}
|
|
157
|
+
];
|
|
158
|
+
};
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
name: 'PriceType';
|
|
162
|
+
type: {
|
|
163
|
+
kind: 'enum';
|
|
164
|
+
variants: [
|
|
165
|
+
{
|
|
166
|
+
name: 'Limit';
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
name: 'Oracle';
|
|
170
|
+
}
|
|
171
|
+
];
|
|
172
|
+
};
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
name: 'MarketType';
|
|
176
|
+
type: {
|
|
177
|
+
kind: 'enum';
|
|
178
|
+
variants: [
|
|
179
|
+
{
|
|
180
|
+
name: 'Perp';
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
name: 'Spot';
|
|
184
|
+
}
|
|
185
|
+
];
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
];
|
|
189
|
+
errors: [
|
|
190
|
+
{
|
|
191
|
+
code: 6000;
|
|
192
|
+
name: 'BidNotCrossed';
|
|
193
|
+
msg: 'BidNotCrossed';
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
code: 6001;
|
|
197
|
+
name: 'AskNotCrossed';
|
|
198
|
+
msg: 'AskNotCrossed';
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
code: 6002;
|
|
202
|
+
name: 'TakerOrderNotFound';
|
|
203
|
+
msg: 'TakerOrderNotFound';
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
code: 6003;
|
|
207
|
+
name: 'OrderSizeBreached';
|
|
208
|
+
msg: 'OrderSizeBreached';
|
|
209
|
+
}
|
|
210
|
+
];
|
|
211
|
+
};
|
|
212
|
+
export declare const IDL: JitProxy;
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.IDL = void 0;
|
|
4
|
+
exports.IDL = {
|
|
5
|
+
version: '0.10.2',
|
|
6
|
+
name: 'jit_proxy',
|
|
7
|
+
instructions: [
|
|
8
|
+
{
|
|
9
|
+
name: 'jit',
|
|
10
|
+
accounts: [
|
|
11
|
+
{
|
|
12
|
+
name: 'state',
|
|
13
|
+
isMut: false,
|
|
14
|
+
isSigner: false,
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
name: 'user',
|
|
18
|
+
isMut: true,
|
|
19
|
+
isSigner: false,
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
name: 'userStats',
|
|
23
|
+
isMut: true,
|
|
24
|
+
isSigner: false,
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
name: 'taker',
|
|
28
|
+
isMut: true,
|
|
29
|
+
isSigner: false,
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: 'takerStats',
|
|
33
|
+
isMut: true,
|
|
34
|
+
isSigner: false,
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: 'authority',
|
|
38
|
+
isMut: false,
|
|
39
|
+
isSigner: true,
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: 'driftProgram',
|
|
43
|
+
isMut: false,
|
|
44
|
+
isSigner: false,
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
args: [
|
|
48
|
+
{
|
|
49
|
+
name: 'params',
|
|
50
|
+
type: {
|
|
51
|
+
defined: 'JitParams',
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
name: 'checkOrderConstraints',
|
|
58
|
+
accounts: [
|
|
59
|
+
{
|
|
60
|
+
name: 'user',
|
|
61
|
+
isMut: false,
|
|
62
|
+
isSigner: false,
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
args: [
|
|
66
|
+
{
|
|
67
|
+
name: 'constraints',
|
|
68
|
+
type: {
|
|
69
|
+
vec: {
|
|
70
|
+
defined: 'OrderConstraint',
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
types: [
|
|
78
|
+
{
|
|
79
|
+
name: 'JitParams',
|
|
80
|
+
type: {
|
|
81
|
+
kind: 'struct',
|
|
82
|
+
fields: [
|
|
83
|
+
{
|
|
84
|
+
name: 'takerOrderId',
|
|
85
|
+
type: 'u32',
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
name: 'maxPosition',
|
|
89
|
+
type: 'i64',
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
name: 'minPosition',
|
|
93
|
+
type: 'i64',
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
name: 'bid',
|
|
97
|
+
type: 'i64',
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
name: 'ask',
|
|
101
|
+
type: 'i64',
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
name: 'priceType',
|
|
105
|
+
type: {
|
|
106
|
+
defined: 'PriceType',
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
name: 'postOnly',
|
|
111
|
+
type: {
|
|
112
|
+
option: {
|
|
113
|
+
defined: 'PostOnlyParam',
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
],
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
name: 'OrderConstraint',
|
|
122
|
+
type: {
|
|
123
|
+
kind: 'struct',
|
|
124
|
+
fields: [
|
|
125
|
+
{
|
|
126
|
+
name: 'maxPosition',
|
|
127
|
+
type: 'i64',
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
name: 'minPosition',
|
|
131
|
+
type: 'i64',
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
name: 'marketIndex',
|
|
135
|
+
type: 'u16',
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
name: 'marketType',
|
|
139
|
+
type: {
|
|
140
|
+
defined: 'MarketType',
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
],
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
name: 'PostOnlyParam',
|
|
148
|
+
type: {
|
|
149
|
+
kind: 'enum',
|
|
150
|
+
variants: [
|
|
151
|
+
{
|
|
152
|
+
name: 'None',
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
name: 'MustPostOnly',
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
name: 'TryPostOnly',
|
|
159
|
+
},
|
|
160
|
+
],
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
name: 'PriceType',
|
|
165
|
+
type: {
|
|
166
|
+
kind: 'enum',
|
|
167
|
+
variants: [
|
|
168
|
+
{
|
|
169
|
+
name: 'Limit',
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
name: 'Oracle',
|
|
173
|
+
},
|
|
174
|
+
],
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
name: 'MarketType',
|
|
179
|
+
type: {
|
|
180
|
+
kind: 'enum',
|
|
181
|
+
variants: [
|
|
182
|
+
{
|
|
183
|
+
name: 'Perp',
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
name: 'Spot',
|
|
187
|
+
},
|
|
188
|
+
],
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
],
|
|
192
|
+
errors: [
|
|
193
|
+
{
|
|
194
|
+
code: 6000,
|
|
195
|
+
name: 'BidNotCrossed',
|
|
196
|
+
msg: 'BidNotCrossed',
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
code: 6001,
|
|
200
|
+
name: 'AskNotCrossed',
|
|
201
|
+
msg: 'AskNotCrossed',
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
code: 6002,
|
|
205
|
+
name: 'TakerOrderNotFound',
|
|
206
|
+
msg: 'TakerOrderNotFound',
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
code: 6003,
|
|
210
|
+
name: 'OrderSizeBreached',
|
|
211
|
+
msg: 'OrderSizeBreached',
|
|
212
|
+
},
|
|
213
|
+
],
|
|
214
|
+
};
|
package/package.json
CHANGED
package/src/types/jit_proxy.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export type JitProxy = {
|
|
2
|
-
version: '0.10.
|
|
2
|
+
version: '0.10.2';
|
|
3
3
|
name: 'jit_proxy';
|
|
4
4
|
instructions: [
|
|
5
5
|
{
|
|
@@ -211,7 +211,7 @@ export type JitProxy = {
|
|
|
211
211
|
};
|
|
212
212
|
|
|
213
213
|
export const IDL: JitProxy = {
|
|
214
|
-
version: '0.10.
|
|
214
|
+
version: '0.10.2',
|
|
215
215
|
name: 'jit_proxy',
|
|
216
216
|
instructions: [
|
|
217
217
|
{
|