@drift-labs/sdk 2.74.0-beta.7 → 2.74.0-beta.9
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/VERSION +1 -1
- package/lib/adminClient.d.ts +1 -0
- package/lib/adminClient.js +13 -0
- package/lib/dlob/orderBookLevels.js +41 -12
- package/lib/idl/drift.json +3 -0
- package/lib/math/funding.js +0 -6
- package/lib/math/oracles.js +1 -1
- package/lib/math/tiers.js +1 -1
- package/lib/oracles/prelaunchOracleClient.js +1 -0
- package/lib/oracles/types.d.ts +1 -0
- package/lib/types.d.ts +3 -0
- package/lib/types.js +1 -0
- package/package.json +1 -1
- package/src/adminClient.ts +26 -0
- package/src/dlob/orderBookLevels.ts +45 -15
- package/src/idl/drift.json +3 -0
- package/src/math/funding.ts +0 -4
- package/src/math/oracles.ts +1 -1
- package/src/math/tiers.ts +1 -1
- package/src/oracles/prelaunchOracleClient.ts +1 -0
- package/src/oracles/types.ts +1 -0
- package/src/types.ts +1 -0
- package/tests/dlob/test.ts +57 -0
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.74.0-beta.
|
|
1
|
+
2.74.0-beta.9
|
package/lib/adminClient.d.ts
CHANGED
|
@@ -83,4 +83,5 @@ export declare class AdminClient extends DriftClient {
|
|
|
83
83
|
updateProtocolIfSharesTransferConfig(whitelistedSigners?: PublicKey[], maxTransferPerEpoch?: BN): Promise<TransactionSignature>;
|
|
84
84
|
initializePrelaunchOracle(perpMarketIndex: number, price?: BN, maxPrice?: BN): Promise<TransactionSignature>;
|
|
85
85
|
updatePrelaunchOracleParams(perpMarketIndex: number, price?: BN, maxPrice?: BN): Promise<TransactionSignature>;
|
|
86
|
+
deletePrelaunchOracle(perpMarketIndex: number): Promise<TransactionSignature>;
|
|
86
87
|
}
|
package/lib/adminClient.js
CHANGED
|
@@ -1083,5 +1083,18 @@ class AdminClient extends driftClient_1.DriftClient {
|
|
|
1083
1083
|
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
1084
1084
|
return txSig;
|
|
1085
1085
|
}
|
|
1086
|
+
async deletePrelaunchOracle(perpMarketIndex) {
|
|
1087
|
+
const deletePrelaunchOracleIx = await this.program.instruction.deletePrelaunchOracle(perpMarketIndex, {
|
|
1088
|
+
accounts: {
|
|
1089
|
+
admin: this.wallet.publicKey,
|
|
1090
|
+
state: await this.getStatePublicKey(),
|
|
1091
|
+
prelaunchOracle: await (0, pda_1.getPrelaunchOraclePublicKey)(this.program.programId, perpMarketIndex),
|
|
1092
|
+
perpMarket: await (0, pda_1.getPerpMarketPublicKey)(this.program.programId, perpMarketIndex),
|
|
1093
|
+
},
|
|
1094
|
+
});
|
|
1095
|
+
const tx = await this.buildTransaction(deletePrelaunchOracleIx);
|
|
1096
|
+
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
1097
|
+
return txSig;
|
|
1098
|
+
}
|
|
1086
1099
|
}
|
|
1087
1100
|
exports.AdminClient = AdminClient;
|
|
@@ -261,6 +261,31 @@ function groupL2Levels(levels, grouping, direction, depth) {
|
|
|
261
261
|
}
|
|
262
262
|
return groupedLevels;
|
|
263
263
|
}
|
|
264
|
+
/**
|
|
265
|
+
* Method to merge bids or asks by price
|
|
266
|
+
*/
|
|
267
|
+
const mergeByPrice = (bidsOrAsks) => {
|
|
268
|
+
const merged = new Map();
|
|
269
|
+
for (const level of bidsOrAsks) {
|
|
270
|
+
const key = level.price.toString();
|
|
271
|
+
if (merged.has(key)) {
|
|
272
|
+
const existing = merged.get(key);
|
|
273
|
+
existing.size = existing.size.add(level.size);
|
|
274
|
+
for (const [source, size] of Object.entries(level.sources)) {
|
|
275
|
+
if (existing.sources[source]) {
|
|
276
|
+
existing.sources[source] = existing.sources[source].add(size);
|
|
277
|
+
}
|
|
278
|
+
else {
|
|
279
|
+
existing.sources[source] = size;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
else {
|
|
284
|
+
merged.set(key, cloneL2Level(level));
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return Array.from(merged.values());
|
|
288
|
+
};
|
|
264
289
|
/**
|
|
265
290
|
* The purpose of this function is uncross the L2 orderbook by modifying the bid/ask price at the top of the book
|
|
266
291
|
* This will make the liquidity look worse but more intuitive (users familiar with clob get confused w temporarily
|
|
@@ -342,17 +367,17 @@ function uncrossL2(bids, asks, oraclePrice, oracleTwap5Min, markTwap5Min, groupi
|
|
|
342
367
|
bidIndex++;
|
|
343
368
|
continue;
|
|
344
369
|
}
|
|
370
|
+
if (userBids.has(nextBid.price.toString())) {
|
|
371
|
+
newBids.push(nextBid);
|
|
372
|
+
bidIndex++;
|
|
373
|
+
continue;
|
|
374
|
+
}
|
|
375
|
+
if (userAsks.has(nextAsk.price.toString())) {
|
|
376
|
+
newAsks.push(nextAsk);
|
|
377
|
+
askIndex++;
|
|
378
|
+
continue;
|
|
379
|
+
}
|
|
345
380
|
if (nextBid.price.gte(nextAsk.price)) {
|
|
346
|
-
if (userBids.has(nextBid.price.toString())) {
|
|
347
|
-
newBids.push(nextBid);
|
|
348
|
-
bidIndex++;
|
|
349
|
-
continue;
|
|
350
|
-
}
|
|
351
|
-
if (userAsks.has(nextAsk.price.toString())) {
|
|
352
|
-
newAsks.push(nextAsk);
|
|
353
|
-
askIndex++;
|
|
354
|
-
continue;
|
|
355
|
-
}
|
|
356
381
|
if (nextBid.price.gt(referencePrice) &&
|
|
357
382
|
nextAsk.price.gt(referencePrice)) {
|
|
358
383
|
let newBidPrice = nextAsk.price.sub(grouping);
|
|
@@ -397,9 +422,13 @@ function uncrossL2(bids, asks, oraclePrice, oracleTwap5Min, markTwap5Min, groupi
|
|
|
397
422
|
bidIndex++;
|
|
398
423
|
}
|
|
399
424
|
}
|
|
425
|
+
newBids.sort((a, b) => b.price.cmp(a.price));
|
|
426
|
+
newAsks.sort((a, b) => a.price.cmp(b.price));
|
|
427
|
+
const finalNewBids = mergeByPrice(newBids);
|
|
428
|
+
const finalNewAsks = mergeByPrice(newAsks);
|
|
400
429
|
return {
|
|
401
|
-
bids:
|
|
402
|
-
asks:
|
|
430
|
+
bids: finalNewBids,
|
|
431
|
+
asks: finalNewAsks,
|
|
403
432
|
};
|
|
404
433
|
}
|
|
405
434
|
exports.uncrossL2 = uncrossL2;
|
package/lib/idl/drift.json
CHANGED
package/lib/math/funding.js
CHANGED
|
@@ -148,12 +148,6 @@ function getMaxPriceDivergenceForFundingRate(market, oracleTwap) {
|
|
|
148
148
|
else if ((0, types_1.isVariant)(market.contractTier, 'c')) {
|
|
149
149
|
return oracleTwap.divn(20);
|
|
150
150
|
}
|
|
151
|
-
else if ((0, types_1.isVariant)(market.contractTier, 'speculative')) {
|
|
152
|
-
return oracleTwap.divn(10);
|
|
153
|
-
}
|
|
154
|
-
else if ((0, types_1.isVariant)(market.contractTier, 'isolated')) {
|
|
155
|
-
return oracleTwap.divn(10);
|
|
156
|
-
}
|
|
157
151
|
else {
|
|
158
152
|
return oracleTwap.divn(10);
|
|
159
153
|
}
|
package/lib/math/oracles.js
CHANGED
|
@@ -28,7 +28,7 @@ function getMaxConfidenceIntervalMultiplier(market) {
|
|
|
28
28
|
else if ((0, types_1.isVariant)(market.contractTier, 'speculative')) {
|
|
29
29
|
maxConfidenceIntervalMultiplier = new index_1.BN(10);
|
|
30
30
|
}
|
|
31
|
-
else
|
|
31
|
+
else {
|
|
32
32
|
maxConfidenceIntervalMultiplier = new index_1.BN(50);
|
|
33
33
|
}
|
|
34
34
|
return maxConfidenceIntervalMultiplier;
|
package/lib/math/tiers.js
CHANGED
|
@@ -15,7 +15,7 @@ function getPerpMarketTierNumber(perpMarket) {
|
|
|
15
15
|
else if ((0, types_1.isVariant)(perpMarket.contractTier, 'speculative')) {
|
|
16
16
|
return 3;
|
|
17
17
|
}
|
|
18
|
-
else if ((0, types_1.isVariant)(perpMarket.contractTier, '
|
|
18
|
+
else if ((0, types_1.isVariant)(perpMarket.contractTier, 'highlySpeculative')) {
|
|
19
19
|
return 4;
|
|
20
20
|
}
|
|
21
21
|
else {
|
package/lib/oracles/types.d.ts
CHANGED
package/lib/types.d.ts
CHANGED
package/lib/types.js
CHANGED
|
@@ -60,6 +60,7 @@ ContractTier.A = { a: {} };
|
|
|
60
60
|
ContractTier.B = { b: {} };
|
|
61
61
|
ContractTier.C = { c: {} };
|
|
62
62
|
ContractTier.SPECULATIVE = { speculative: {} };
|
|
63
|
+
ContractTier.HIGHLY_SPECULATIVE = { highlySpeculative: {} };
|
|
63
64
|
ContractTier.ISOLATED = { isolated: {} };
|
|
64
65
|
class AssetTier {
|
|
65
66
|
}
|
package/package.json
CHANGED
package/src/adminClient.ts
CHANGED
|
@@ -2172,4 +2172,30 @@ export class AdminClient extends DriftClient {
|
|
|
2172
2172
|
|
|
2173
2173
|
return txSig;
|
|
2174
2174
|
}
|
|
2175
|
+
|
|
2176
|
+
public async deletePrelaunchOracle(
|
|
2177
|
+
perpMarketIndex: number
|
|
2178
|
+
): Promise<TransactionSignature> {
|
|
2179
|
+
const deletePrelaunchOracleIx =
|
|
2180
|
+
await this.program.instruction.deletePrelaunchOracle(perpMarketIndex, {
|
|
2181
|
+
accounts: {
|
|
2182
|
+
admin: this.wallet.publicKey,
|
|
2183
|
+
state: await this.getStatePublicKey(),
|
|
2184
|
+
prelaunchOracle: await getPrelaunchOraclePublicKey(
|
|
2185
|
+
this.program.programId,
|
|
2186
|
+
perpMarketIndex
|
|
2187
|
+
),
|
|
2188
|
+
perpMarket: await getPerpMarketPublicKey(
|
|
2189
|
+
this.program.programId,
|
|
2190
|
+
perpMarketIndex
|
|
2191
|
+
),
|
|
2192
|
+
},
|
|
2193
|
+
});
|
|
2194
|
+
|
|
2195
|
+
const tx = await this.buildTransaction(deletePrelaunchOracleIx);
|
|
2196
|
+
|
|
2197
|
+
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
2198
|
+
|
|
2199
|
+
return txSig;
|
|
2200
|
+
}
|
|
2175
2201
|
}
|
|
@@ -429,6 +429,30 @@ function groupL2Levels(
|
|
|
429
429
|
return groupedLevels;
|
|
430
430
|
}
|
|
431
431
|
|
|
432
|
+
/**
|
|
433
|
+
* Method to merge bids or asks by price
|
|
434
|
+
*/
|
|
435
|
+
const mergeByPrice = (bidsOrAsks: L2Level[]) => {
|
|
436
|
+
const merged = new Map<string, L2Level>();
|
|
437
|
+
for (const level of bidsOrAsks) {
|
|
438
|
+
const key = level.price.toString();
|
|
439
|
+
if (merged.has(key)) {
|
|
440
|
+
const existing = merged.get(key);
|
|
441
|
+
existing.size = existing.size.add(level.size);
|
|
442
|
+
for (const [source, size] of Object.entries(level.sources)) {
|
|
443
|
+
if (existing.sources[source]) {
|
|
444
|
+
existing.sources[source] = existing.sources[source].add(size);
|
|
445
|
+
} else {
|
|
446
|
+
existing.sources[source] = size;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
} else {
|
|
450
|
+
merged.set(key, cloneL2Level(level));
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
return Array.from(merged.values());
|
|
454
|
+
};
|
|
455
|
+
|
|
432
456
|
/**
|
|
433
457
|
* The purpose of this function is uncross the L2 orderbook by modifying the bid/ask price at the top of the book
|
|
434
458
|
* This will make the liquidity look worse but more intuitive (users familiar with clob get confused w temporarily
|
|
@@ -467,8 +491,8 @@ export function uncrossL2(
|
|
|
467
491
|
return { bids, asks };
|
|
468
492
|
}
|
|
469
493
|
|
|
470
|
-
const newBids = [];
|
|
471
|
-
const newAsks = [];
|
|
494
|
+
const newBids: L2Level[] = [];
|
|
495
|
+
const newAsks: L2Level[] = [];
|
|
472
496
|
|
|
473
497
|
const updateLevels = (newPrice: BN, oldLevel: L2Level, levels: L2Level[]) => {
|
|
474
498
|
if (levels.length > 0 && levels[levels.length - 1].price.eq(newPrice)) {
|
|
@@ -528,19 +552,19 @@ export function uncrossL2(
|
|
|
528
552
|
continue;
|
|
529
553
|
}
|
|
530
554
|
|
|
531
|
-
if (nextBid.price.
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
}
|
|
555
|
+
if (userBids.has(nextBid.price.toString())) {
|
|
556
|
+
newBids.push(nextBid);
|
|
557
|
+
bidIndex++;
|
|
558
|
+
continue;
|
|
559
|
+
}
|
|
537
560
|
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
561
|
+
if (userAsks.has(nextAsk.price.toString())) {
|
|
562
|
+
newAsks.push(nextAsk);
|
|
563
|
+
askIndex++;
|
|
564
|
+
continue;
|
|
565
|
+
}
|
|
543
566
|
|
|
567
|
+
if (nextBid.price.gte(nextAsk.price)) {
|
|
544
568
|
if (
|
|
545
569
|
nextBid.price.gt(referencePrice) &&
|
|
546
570
|
nextAsk.price.gt(referencePrice)
|
|
@@ -594,8 +618,14 @@ export function uncrossL2(
|
|
|
594
618
|
}
|
|
595
619
|
}
|
|
596
620
|
|
|
621
|
+
newBids.sort((a, b) => b.price.cmp(a.price));
|
|
622
|
+
newAsks.sort((a, b) => a.price.cmp(b.price));
|
|
623
|
+
|
|
624
|
+
const finalNewBids = mergeByPrice(newBids);
|
|
625
|
+
const finalNewAsks = mergeByPrice(newAsks);
|
|
626
|
+
|
|
597
627
|
return {
|
|
598
|
-
bids:
|
|
599
|
-
asks:
|
|
628
|
+
bids: finalNewBids,
|
|
629
|
+
asks: finalNewAsks,
|
|
600
630
|
};
|
|
601
631
|
}
|
package/src/idl/drift.json
CHANGED
package/src/math/funding.ts
CHANGED
|
@@ -252,10 +252,6 @@ function getMaxPriceDivergenceForFundingRate(
|
|
|
252
252
|
return oracleTwap.divn(33);
|
|
253
253
|
} else if (isVariant(market.contractTier, 'c')) {
|
|
254
254
|
return oracleTwap.divn(20);
|
|
255
|
-
} else if (isVariant(market.contractTier, 'speculative')) {
|
|
256
|
-
return oracleTwap.divn(10);
|
|
257
|
-
} else if (isVariant(market.contractTier, 'isolated')) {
|
|
258
|
-
return oracleTwap.divn(10);
|
|
259
255
|
} else {
|
|
260
256
|
return oracleTwap.divn(10);
|
|
261
257
|
}
|
package/src/math/oracles.ts
CHANGED
|
@@ -39,7 +39,7 @@ export function getMaxConfidenceIntervalMultiplier(
|
|
|
39
39
|
maxConfidenceIntervalMultiplier = new BN(2);
|
|
40
40
|
} else if (isVariant(market.contractTier, 'speculative')) {
|
|
41
41
|
maxConfidenceIntervalMultiplier = new BN(10);
|
|
42
|
-
} else
|
|
42
|
+
} else {
|
|
43
43
|
maxConfidenceIntervalMultiplier = new BN(50);
|
|
44
44
|
}
|
|
45
45
|
return maxConfidenceIntervalMultiplier;
|
package/src/math/tiers.ts
CHANGED
|
@@ -9,7 +9,7 @@ export function getPerpMarketTierNumber(perpMarket: PerpMarketAccount): number {
|
|
|
9
9
|
return 2;
|
|
10
10
|
} else if (isVariant(perpMarket.contractTier, 'speculative')) {
|
|
11
11
|
return 3;
|
|
12
|
-
} else if (isVariant(perpMarket.contractTier, '
|
|
12
|
+
} else if (isVariant(perpMarket.contractTier, 'highlySpeculative')) {
|
|
13
13
|
return 4;
|
|
14
14
|
} else {
|
|
15
15
|
return 5;
|
package/src/oracles/types.ts
CHANGED
package/src/types.ts
CHANGED
|
@@ -58,6 +58,7 @@ export class ContractTier {
|
|
|
58
58
|
static readonly B = { b: {} };
|
|
59
59
|
static readonly C = { c: {} };
|
|
60
60
|
static readonly SPECULATIVE = { speculative: {} };
|
|
61
|
+
static readonly HIGHLY_SPECULATIVE = { highlySpeculative: {} };
|
|
61
62
|
static readonly ISOLATED = { isolated: {} };
|
|
62
63
|
}
|
|
63
64
|
|
package/tests/dlob/test.ts
CHANGED
|
@@ -6614,6 +6614,63 @@ describe('Uncross L2', () => {
|
|
|
6614
6614
|
);
|
|
6615
6615
|
});
|
|
6616
6616
|
|
|
6617
|
+
it('Handles user crossing bid in second level', () => {
|
|
6618
|
+
const oraclePrice = new BN(190.3843 * PRICE_PRECISION.toNumber());
|
|
6619
|
+
const bids = [
|
|
6620
|
+
[190.59, 2],
|
|
6621
|
+
[190.588, 58.3],
|
|
6622
|
+
[190.5557, 5],
|
|
6623
|
+
[190.5547, 5],
|
|
6624
|
+
[190.5508, 5],
|
|
6625
|
+
[190.541, 2],
|
|
6626
|
+
[190.5099, 49.1],
|
|
6627
|
+
[190.5, 60],
|
|
6628
|
+
].map(([price, size]) => ({
|
|
6629
|
+
price: new BN(price * PRICE_PRECISION.toNumber()),
|
|
6630
|
+
size: new BN(size * BASE_PRECISION.toNumber()),
|
|
6631
|
+
sources: { vamm: new BN(size * BASE_PRECISION.toNumber()) },
|
|
6632
|
+
}));
|
|
6633
|
+
|
|
6634
|
+
const asks = [
|
|
6635
|
+
[190.5, 86.5],
|
|
6636
|
+
[190.6159, 1],
|
|
6637
|
+
[190.656, 10.5],
|
|
6638
|
+
[190.6561, 1],
|
|
6639
|
+
[190.6585, 5],
|
|
6640
|
+
[190.6595, 5],
|
|
6641
|
+
[190.6596, 5],
|
|
6642
|
+
].map(([price, size]) => ({
|
|
6643
|
+
price: new BN(price * PRICE_PRECISION.toNumber()),
|
|
6644
|
+
size: new BN(size * BASE_PRECISION.toNumber()),
|
|
6645
|
+
sources: { vamm: new BN(size * BASE_PRECISION.toNumber()) },
|
|
6646
|
+
}));
|
|
6647
|
+
|
|
6648
|
+
expect(asksAreSortedAsc(asks), 'Input asks are ascending').to.be.true;
|
|
6649
|
+
expect(bidsAreSortedDesc(bids), 'Input bids are descending').to.be.true;
|
|
6650
|
+
|
|
6651
|
+
const groupingSize = new BN('100');
|
|
6652
|
+
|
|
6653
|
+
const userBidPrice = new BN(190.588 * PRICE_PRECISION.toNumber());
|
|
6654
|
+
const userBids = new Set<string>([userBidPrice.toString()]);
|
|
6655
|
+
|
|
6656
|
+
const { bids: newBids, asks: newAsks } = uncrossL2(
|
|
6657
|
+
bids,
|
|
6658
|
+
asks,
|
|
6659
|
+
oraclePrice,
|
|
6660
|
+
oraclePrice,
|
|
6661
|
+
oraclePrice,
|
|
6662
|
+
groupingSize,
|
|
6663
|
+
userBids,
|
|
6664
|
+
new Set<string>()
|
|
6665
|
+
);
|
|
6666
|
+
|
|
6667
|
+
expect(asksAreSortedAsc(newAsks), 'Uncrossed asks are ascending').to.be
|
|
6668
|
+
.true;
|
|
6669
|
+
expect(bidsAreSortedDesc(newBids), 'Uncrossed bids are descending').to.be
|
|
6670
|
+
.true;
|
|
6671
|
+
expect(newBids[0].price.toString()).to.equal(userBidPrice.toString());
|
|
6672
|
+
});
|
|
6673
|
+
|
|
6617
6674
|
it('Handles edge case bide and asks with large cross and an overlapping level', () => {
|
|
6618
6675
|
const bids = [
|
|
6619
6676
|
'104411000',
|