@drift-labs/sdk 2.74.0-beta.0 → 2.74.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/VERSION +1 -1
- package/lib/adminClient.d.ts +5 -2
- package/lib/adminClient.js +17 -4
- package/lib/blockhashSubscriber/BlockhashSubscriber.d.ts +21 -0
- package/lib/blockhashSubscriber/BlockhashSubscriber.js +73 -0
- package/lib/blockhashSubscriber/index.d.ts +1 -0
- package/lib/blockhashSubscriber/index.js +17 -0
- package/lib/blockhashSubscriber/types.d.ts +7 -0
- package/lib/blockhashSubscriber/types.js +2 -0
- package/lib/dlob/orderBookLevels.js +47 -12
- package/lib/driftClient.d.ts +5 -0
- package/lib/driftClient.js +17 -0
- package/lib/events/parse.d.ts +1 -1
- package/lib/events/parse.js +12 -12
- package/lib/idl/drift.json +89 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -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/priorityFee/priorityFeeSubscriber.d.ts +1 -0
- package/lib/priorityFee/priorityFeeSubscriber.js +3 -0
- package/lib/tx/baseTxSender.d.ts +1 -1
- package/lib/tx/baseTxSender.js +9 -2
- package/lib/tx/fastSingleTxSender.d.ts +1 -1
- package/lib/tx/fastSingleTxSender.js +11 -3
- package/lib/tx/types.d.ts +1 -1
- package/lib/types.d.ts +3 -0
- package/lib/types.js +1 -0
- package/lib/user.d.ts +6 -4
- package/lib/user.js +24 -21
- package/package.json +1 -1
- package/src/adminClient.ts +73 -1
- package/src/blockhashSubscriber/BlockhashSubscriber.ts +108 -0
- package/src/blockhashSubscriber/index.ts +1 -0
- package/src/blockhashSubscriber/types.ts +8 -0
- package/src/dlob/orderBookLevels.ts +51 -15
- package/src/driftClient.ts +37 -0
- package/src/events/parse.ts +26 -12
- package/src/idl/drift.json +89 -1
- package/src/index.ts +1 -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/priorityFee/priorityFeeSubscriber.ts +4 -0
- package/src/tx/baseTxSender.ts +12 -4
- package/src/tx/fastSingleTxSender.ts +13 -5
- package/src/tx/types.ts +2 -1
- package/src/types.ts +1 -0
- package/src/user.ts +32 -30
- package/tests/amm/test.ts +3 -1
- package/tests/dlob/test.ts +57 -0
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.74.0-beta.
|
|
1
|
+
2.74.0-beta.10
|
package/lib/adminClient.d.ts
CHANGED
|
@@ -5,10 +5,12 @@ import { BN } from '@coral-xyz/anchor';
|
|
|
5
5
|
import { DriftClient } from './driftClient';
|
|
6
6
|
export declare class AdminClient extends DriftClient {
|
|
7
7
|
initialize(usdcMint: PublicKey, _adminControlsPrices: boolean): Promise<[TransactionSignature]>;
|
|
8
|
-
initializeSpotMarket(mint: PublicKey, optimalUtilization: number, optimalRate: number, maxRate: number, oracle: PublicKey, oracleSource: OracleSource, initialAssetWeight: number, maintenanceAssetWeight: number, initialLiabilityWeight: number, maintenanceLiabilityWeight: number, imfFactor?: number, liquidatorFee?: number, activeStatus?: boolean,
|
|
8
|
+
initializeSpotMarket(mint: PublicKey, optimalUtilization: number, optimalRate: number, maxRate: number, oracle: PublicKey, oracleSource: OracleSource, initialAssetWeight: number, maintenanceAssetWeight: number, initialLiabilityWeight: number, maintenanceLiabilityWeight: number, imfFactor?: number, liquidatorFee?: number, ifLiquidationFee?: number, activeStatus?: boolean, assetTier?: {
|
|
9
|
+
collateral: {};
|
|
10
|
+
}, scaleInitialAssetWeightStart?: BN, withdrawGuardThreshold?: BN, orderTickSize?: BN, orderStepSize?: BN, ifTotalFactor?: number, name?: string): Promise<TransactionSignature>;
|
|
9
11
|
initializeSerumFulfillmentConfig(marketIndex: number, serumMarket: PublicKey, serumProgram: PublicKey): Promise<TransactionSignature>;
|
|
10
12
|
initializePhoenixFulfillmentConfig(marketIndex: number, phoenixMarket: PublicKey): Promise<TransactionSignature>;
|
|
11
|
-
initializePerpMarket(marketIndex: number, priceOracle: PublicKey, baseAssetReserve: BN, quoteAssetReserve: BN, periodicity: BN, pegMultiplier?: BN, oracleSource?: OracleSource, marginRatioInitial?: number, marginRatioMaintenance?: number, liquidatorFee?: number, activeStatus?: boolean, name?: string): Promise<TransactionSignature>;
|
|
13
|
+
initializePerpMarket(marketIndex: number, priceOracle: PublicKey, baseAssetReserve: BN, quoteAssetReserve: BN, periodicity: BN, pegMultiplier?: BN, oracleSource?: OracleSource, marginRatioInitial?: number, marginRatioMaintenance?: number, liquidatorFee?: number, ifLiquidatorFee?: number, imfFactor?: number, activeStatus?: boolean, baseSpread?: number, maxSpread?: number, maxOpenInterest?: BN, maxRevenueWithdrawPerPeriod?: BN, quoteMaxInsurance?: BN, orderStepSize?: BN, orderTickSize?: BN, minOrderSize?: BN, concentrationCoefScale?: BN, curveUpdateIntensity?: number, ammJitIntensity?: number, name?: string): Promise<TransactionSignature>;
|
|
12
14
|
deleteInitializedPerpMarket(marketIndex: number): Promise<TransactionSignature>;
|
|
13
15
|
moveAmmPrice(perpMarketIndex: number, baseAssetReserve: BN, quoteAssetReserve: BN, sqrtK?: BN): Promise<TransactionSignature>;
|
|
14
16
|
updateK(perpMarketIndex: number, sqrtK: BN): Promise<TransactionSignature>;
|
|
@@ -83,4 +85,5 @@ export declare class AdminClient extends DriftClient {
|
|
|
83
85
|
updateProtocolIfSharesTransferConfig(whitelistedSigners?: PublicKey[], maxTransferPerEpoch?: BN): Promise<TransactionSignature>;
|
|
84
86
|
initializePrelaunchOracle(perpMarketIndex: number, price?: BN, maxPrice?: BN): Promise<TransactionSignature>;
|
|
85
87
|
updatePrelaunchOracleParams(perpMarketIndex: number, price?: BN, maxPrice?: BN): Promise<TransactionSignature>;
|
|
88
|
+
deletePrelaunchOracle(perpMarketIndex: number): Promise<TransactionSignature>;
|
|
86
89
|
}
|
package/lib/adminClient.js
CHANGED
|
@@ -59,13 +59,13 @@ class AdminClient extends driftClient_1.DriftClient {
|
|
|
59
59
|
const { txSig } = await super.sendTransaction(tx, [], this.opts);
|
|
60
60
|
return [txSig];
|
|
61
61
|
}
|
|
62
|
-
async initializeSpotMarket(mint, optimalUtilization, optimalRate, maxRate, oracle, oracleSource, initialAssetWeight, maintenanceAssetWeight, initialLiabilityWeight, maintenanceLiabilityWeight, imfFactor = 0, liquidatorFee = 0, activeStatus = true, name = userName_1.DEFAULT_MARKET_NAME) {
|
|
62
|
+
async initializeSpotMarket(mint, optimalUtilization, optimalRate, maxRate, oracle, oracleSource, initialAssetWeight, maintenanceAssetWeight, initialLiabilityWeight, maintenanceLiabilityWeight, imfFactor = 0, liquidatorFee = 0, ifLiquidationFee = 0, activeStatus = true, assetTier = types_1.AssetTier.COLLATERAL, scaleInitialAssetWeightStart = numericConstants_1.ZERO, withdrawGuardThreshold = numericConstants_1.ZERO, orderTickSize = numericConstants_1.ONE, orderStepSize = numericConstants_1.ONE, ifTotalFactor = 0, name = userName_1.DEFAULT_MARKET_NAME) {
|
|
63
63
|
const spotMarketIndex = this.getStateAccount().numberOfSpotMarkets;
|
|
64
64
|
const spotMarket = await (0, pda_1.getSpotMarketPublicKey)(this.program.programId, spotMarketIndex);
|
|
65
65
|
const spotMarketVault = await (0, pda_1.getSpotMarketVaultPublicKey)(this.program.programId, spotMarketIndex);
|
|
66
66
|
const insuranceFundVault = await (0, pda_1.getInsuranceFundVaultPublicKey)(this.program.programId, spotMarketIndex);
|
|
67
67
|
const nameBuffer = (0, userName_1.encodeName)(name);
|
|
68
|
-
const initializeIx = await this.program.instruction.initializeSpotMarket(optimalUtilization, optimalRate, maxRate, oracleSource, initialAssetWeight, maintenanceAssetWeight, initialLiabilityWeight, maintenanceLiabilityWeight, imfFactor, liquidatorFee, activeStatus, nameBuffer, {
|
|
68
|
+
const initializeIx = await this.program.instruction.initializeSpotMarket(optimalUtilization, optimalRate, maxRate, oracleSource, initialAssetWeight, maintenanceAssetWeight, initialLiabilityWeight, maintenanceLiabilityWeight, imfFactor, liquidatorFee, ifLiquidationFee, activeStatus, assetTier, scaleInitialAssetWeightStart, withdrawGuardThreshold, orderTickSize, orderStepSize, ifTotalFactor, nameBuffer, {
|
|
69
69
|
accounts: {
|
|
70
70
|
admin: this.wallet.publicKey,
|
|
71
71
|
state: await this.getStatePublicKey(),
|
|
@@ -133,11 +133,11 @@ class AdminClient extends driftClient_1.DriftClient {
|
|
|
133
133
|
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
134
134
|
return txSig;
|
|
135
135
|
}
|
|
136
|
-
async initializePerpMarket(marketIndex, priceOracle, baseAssetReserve, quoteAssetReserve, periodicity, pegMultiplier = numericConstants_1.PEG_PRECISION, oracleSource = types_1.OracleSource.PYTH, marginRatioInitial = 2000, marginRatioMaintenance = 500, liquidatorFee = 0, activeStatus = true, name = userName_1.DEFAULT_MARKET_NAME) {
|
|
136
|
+
async initializePerpMarket(marketIndex, priceOracle, baseAssetReserve, quoteAssetReserve, periodicity, pegMultiplier = numericConstants_1.PEG_PRECISION, oracleSource = types_1.OracleSource.PYTH, marginRatioInitial = 2000, marginRatioMaintenance = 500, liquidatorFee = 0, ifLiquidatorFee = 10000, imfFactor = 0, activeStatus = true, baseSpread = 0, maxSpread = 142500, maxOpenInterest = numericConstants_1.ZERO, maxRevenueWithdrawPerPeriod = numericConstants_1.ZERO, quoteMaxInsurance = numericConstants_1.ZERO, orderStepSize = numericConstants_1.BASE_PRECISION.divn(10000), orderTickSize = numericConstants_1.PRICE_PRECISION.divn(100000), minOrderSize = numericConstants_1.BASE_PRECISION.divn(10000), concentrationCoefScale = numericConstants_1.ONE, curveUpdateIntensity = 0, ammJitIntensity = 0, name = userName_1.DEFAULT_MARKET_NAME) {
|
|
137
137
|
const currentPerpMarketIndex = this.getStateAccount().numberOfMarkets;
|
|
138
138
|
const perpMarketPublicKey = await (0, pda_1.getPerpMarketPublicKey)(this.program.programId, currentPerpMarketIndex);
|
|
139
139
|
const nameBuffer = (0, userName_1.encodeName)(name);
|
|
140
|
-
const initializeMarketIx = await this.program.instruction.initializePerpMarket(marketIndex, baseAssetReserve, quoteAssetReserve, periodicity, pegMultiplier, oracleSource, marginRatioInitial, marginRatioMaintenance, liquidatorFee, activeStatus, nameBuffer, {
|
|
140
|
+
const initializeMarketIx = await this.program.instruction.initializePerpMarket(marketIndex, baseAssetReserve, quoteAssetReserve, periodicity, pegMultiplier, oracleSource, marginRatioInitial, marginRatioMaintenance, liquidatorFee, ifLiquidatorFee, imfFactor, activeStatus, baseSpread, maxSpread, maxOpenInterest, maxRevenueWithdrawPerPeriod, quoteMaxInsurance, orderStepSize, orderTickSize, minOrderSize, concentrationCoefScale, curveUpdateIntensity, ammJitIntensity, nameBuffer, {
|
|
141
141
|
accounts: {
|
|
142
142
|
state: await this.getStatePublicKey(),
|
|
143
143
|
admin: this.wallet.publicKey,
|
|
@@ -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;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { BlockhashWithExpiryBlockHeight, Context } from '@solana/web3.js';
|
|
2
|
+
import { BlockhashSubscriberConfig } from './types';
|
|
3
|
+
export declare class BlockhashSubscriber {
|
|
4
|
+
private connection;
|
|
5
|
+
private isSubscribed;
|
|
6
|
+
private latestBlockHeight;
|
|
7
|
+
private latestBlockHeightContext;
|
|
8
|
+
private blockhashes;
|
|
9
|
+
private updateBlockhashIntervalId;
|
|
10
|
+
private commitment;
|
|
11
|
+
private updateIntervalMs;
|
|
12
|
+
constructor(config: BlockhashSubscriberConfig);
|
|
13
|
+
getBlockhashCacheSize(): number;
|
|
14
|
+
getLatestBlockHeight(): number;
|
|
15
|
+
getLatestBlockHeightContext(): Context | undefined;
|
|
16
|
+
getLatestBlockhash(offset?: number): BlockhashWithExpiryBlockHeight | undefined;
|
|
17
|
+
pruneBlockhashes(): void;
|
|
18
|
+
updateBlockhash(): Promise<void>;
|
|
19
|
+
subscribe(): Promise<void>;
|
|
20
|
+
unsubscribe(): void;
|
|
21
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BlockhashSubscriber = void 0;
|
|
4
|
+
const web3_js_1 = require("@solana/web3.js");
|
|
5
|
+
class BlockhashSubscriber {
|
|
6
|
+
constructor(config) {
|
|
7
|
+
var _a, _b;
|
|
8
|
+
this.isSubscribed = false;
|
|
9
|
+
this.blockhashes = [];
|
|
10
|
+
if (!config.connection && !config.rpcUrl) {
|
|
11
|
+
throw new Error('BlockhashSubscriber requires one of connection or rpcUrl must be provided');
|
|
12
|
+
}
|
|
13
|
+
this.connection = config.connection || new web3_js_1.Connection(config.rpcUrl);
|
|
14
|
+
this.commitment = (_a = config.commitment) !== null && _a !== void 0 ? _a : 'confirmed';
|
|
15
|
+
this.updateIntervalMs = (_b = config.updateIntervalMs) !== null && _b !== void 0 ? _b : 1000;
|
|
16
|
+
}
|
|
17
|
+
getBlockhashCacheSize() {
|
|
18
|
+
return this.blockhashes.length;
|
|
19
|
+
}
|
|
20
|
+
getLatestBlockHeight() {
|
|
21
|
+
return this.latestBlockHeight;
|
|
22
|
+
}
|
|
23
|
+
getLatestBlockHeightContext() {
|
|
24
|
+
return this.latestBlockHeightContext;
|
|
25
|
+
}
|
|
26
|
+
getLatestBlockhash(offset) {
|
|
27
|
+
if (this.blockhashes.length === 0) {
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
const clampedOffset = Math.max(0, Math.min(this.blockhashes.length - 1, offset !== null && offset !== void 0 ? offset : 0));
|
|
31
|
+
return this.blockhashes[this.blockhashes.length - 1 - clampedOffset];
|
|
32
|
+
}
|
|
33
|
+
pruneBlockhashes() {
|
|
34
|
+
if (this.latestBlockHeight) {
|
|
35
|
+
this.blockhashes = this.blockhashes.filter((blockhash) => blockhash.lastValidBlockHeight > this.latestBlockHeight);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
async updateBlockhash() {
|
|
39
|
+
const [resp, lastConfirmedBlockHeight] = await Promise.all([
|
|
40
|
+
this.connection.getLatestBlockhashAndContext({
|
|
41
|
+
commitment: this.commitment,
|
|
42
|
+
}),
|
|
43
|
+
this.connection.getBlockHeight({ commitment: this.commitment }),
|
|
44
|
+
]);
|
|
45
|
+
this.latestBlockHeight = lastConfirmedBlockHeight;
|
|
46
|
+
this.latestBlockHeightContext = resp.context;
|
|
47
|
+
// avoid caching duplicate blockhashes
|
|
48
|
+
if (this.blockhashes.length > 0) {
|
|
49
|
+
if (resp.value.blockhash ===
|
|
50
|
+
this.blockhashes[this.blockhashes.length - 1].blockhash) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
this.blockhashes.push(resp.value);
|
|
55
|
+
this.pruneBlockhashes();
|
|
56
|
+
}
|
|
57
|
+
async subscribe() {
|
|
58
|
+
if (this.isSubscribed) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
this.isSubscribed = true;
|
|
62
|
+
await this.updateBlockhash();
|
|
63
|
+
this.updateBlockhashIntervalId = setInterval(this.updateBlockhash.bind(this), this.updateIntervalMs);
|
|
64
|
+
}
|
|
65
|
+
unsubscribe() {
|
|
66
|
+
if (this.updateBlockhashIntervalId) {
|
|
67
|
+
clearInterval(this.updateBlockhashIntervalId);
|
|
68
|
+
this.updateBlockhashIntervalId = undefined;
|
|
69
|
+
}
|
|
70
|
+
this.isSubscribed = false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
exports.BlockhashSubscriber = BlockhashSubscriber;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './BlockhashSubscriber';
|
|
@@ -0,0 +1,17 @@
|
|
|
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("./BlockhashSubscriber"), exports);
|
|
@@ -122,6 +122,9 @@ function getVammL2Generator({ marketAccount, oraclePriceData, numOrders, now, to
|
|
|
122
122
|
[afterSwapQuoteReserves, afterSwapBaseReserves] =
|
|
123
123
|
(0, __1.calculateAmmReservesAfterSwap)(bidAmm, 'quote', quoteSwapped, __1.SwapDirection.REMOVE);
|
|
124
124
|
baseSwapped = bidAmm.baseAssetReserve.sub(afterSwapBaseReserves).abs();
|
|
125
|
+
if (baseSwapped.eq(__1.ZERO)) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
125
128
|
if (remainingBaseLiquidity.lt(baseSwapped)) {
|
|
126
129
|
baseSwapped = remainingBaseLiquidity;
|
|
127
130
|
[afterSwapQuoteReserves, afterSwapBaseReserves] =
|
|
@@ -170,6 +173,9 @@ function getVammL2Generator({ marketAccount, oraclePriceData, numOrders, now, to
|
|
|
170
173
|
[afterSwapQuoteReserves, afterSwapBaseReserves] =
|
|
171
174
|
(0, __1.calculateAmmReservesAfterSwap)(askAmm, 'quote', quoteSwapped, __1.SwapDirection.ADD);
|
|
172
175
|
baseSwapped = askAmm.baseAssetReserve.sub(afterSwapBaseReserves).abs();
|
|
176
|
+
if (baseSwapped.eq(__1.ZERO)) {
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
173
179
|
if (remainingBaseLiquidity.lt(baseSwapped)) {
|
|
174
180
|
baseSwapped = remainingBaseLiquidity;
|
|
175
181
|
[afterSwapQuoteReserves, afterSwapBaseReserves] =
|
|
@@ -255,6 +261,31 @@ function groupL2Levels(levels, grouping, direction, depth) {
|
|
|
255
261
|
}
|
|
256
262
|
return groupedLevels;
|
|
257
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
|
+
};
|
|
258
289
|
/**
|
|
259
290
|
* The purpose of this function is uncross the L2 orderbook by modifying the bid/ask price at the top of the book
|
|
260
291
|
* This will make the liquidity look worse but more intuitive (users familiar with clob get confused w temporarily
|
|
@@ -336,17 +367,17 @@ function uncrossL2(bids, asks, oraclePrice, oracleTwap5Min, markTwap5Min, groupi
|
|
|
336
367
|
bidIndex++;
|
|
337
368
|
continue;
|
|
338
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
|
+
}
|
|
339
380
|
if (nextBid.price.gte(nextAsk.price)) {
|
|
340
|
-
if (userBids.has(nextBid.price.toString())) {
|
|
341
|
-
newBids.push(nextBid);
|
|
342
|
-
bidIndex++;
|
|
343
|
-
continue;
|
|
344
|
-
}
|
|
345
|
-
if (userAsks.has(nextAsk.price.toString())) {
|
|
346
|
-
newAsks.push(nextAsk);
|
|
347
|
-
askIndex++;
|
|
348
|
-
continue;
|
|
349
|
-
}
|
|
350
381
|
if (nextBid.price.gt(referencePrice) &&
|
|
351
382
|
nextAsk.price.gt(referencePrice)) {
|
|
352
383
|
let newBidPrice = nextAsk.price.sub(grouping);
|
|
@@ -391,9 +422,13 @@ function uncrossL2(bids, asks, oraclePrice, oracleTwap5Min, markTwap5Min, groupi
|
|
|
391
422
|
bidIndex++;
|
|
392
423
|
}
|
|
393
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);
|
|
394
429
|
return {
|
|
395
|
-
bids:
|
|
396
|
-
asks:
|
|
430
|
+
bids: finalNewBids,
|
|
431
|
+
asks: finalNewAsks,
|
|
397
432
|
};
|
|
398
433
|
}
|
|
399
434
|
exports.uncrossL2 = uncrossL2;
|
package/lib/driftClient.d.ts
CHANGED
|
@@ -134,6 +134,11 @@ export declare class DriftClient {
|
|
|
134
134
|
subAccountId: number;
|
|
135
135
|
}[]): Promise<TransactionSignature>;
|
|
136
136
|
getUpdateAdvancedDlpIx(advancedLp: boolean, subAccountId: number): Promise<anchor.web3.TransactionInstruction>;
|
|
137
|
+
updateUserReduceOnly(updates: {
|
|
138
|
+
reduceOnly: boolean;
|
|
139
|
+
subAccountId: number;
|
|
140
|
+
}[]): Promise<TransactionSignature>;
|
|
141
|
+
getUpdateUserReduceOnlyIx(reduceOnly: boolean, subAccountId: number): Promise<anchor.web3.TransactionInstruction>;
|
|
137
142
|
fetchAllUserAccounts(includeIdle?: boolean): Promise<ProgramAccount<UserAccount>[]>;
|
|
138
143
|
getUserAccountsForDelegate(delegate: PublicKey): Promise<UserAccount[]>;
|
|
139
144
|
getUserAccountsAndAddressesForAuthority(authority: PublicKey): Promise<ProgramAccount<UserAccount>[]>;
|
package/lib/driftClient.js
CHANGED
|
@@ -627,6 +627,23 @@ class DriftClient {
|
|
|
627
627
|
});
|
|
628
628
|
return ix;
|
|
629
629
|
}
|
|
630
|
+
async updateUserReduceOnly(updates) {
|
|
631
|
+
const ixs = await Promise.all(updates.map(async ({ reduceOnly, subAccountId }) => {
|
|
632
|
+
return await this.getUpdateUserReduceOnlyIx(reduceOnly, subAccountId);
|
|
633
|
+
}));
|
|
634
|
+
const tx = await this.buildTransaction(ixs, this.txParams);
|
|
635
|
+
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
636
|
+
return txSig;
|
|
637
|
+
}
|
|
638
|
+
async getUpdateUserReduceOnlyIx(reduceOnly, subAccountId) {
|
|
639
|
+
const ix = await this.program.instruction.updateUserReduceOnly(subAccountId, reduceOnly, {
|
|
640
|
+
accounts: {
|
|
641
|
+
user: (0, pda_1.getUserAccountPublicKeySync)(this.program.programId, this.wallet.publicKey, subAccountId),
|
|
642
|
+
authority: this.wallet.publicKey,
|
|
643
|
+
},
|
|
644
|
+
});
|
|
645
|
+
return ix;
|
|
646
|
+
}
|
|
630
647
|
async fetchAllUserAccounts(includeIdle = true) {
|
|
631
648
|
let filters = undefined;
|
|
632
649
|
if (!includeIdle) {
|
package/lib/events/parse.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { Program, Event } from '@coral-xyz/anchor';
|
|
2
|
-
export declare function parseLogs(program: Program, logs: string[]): Event[];
|
|
2
|
+
export declare function parseLogs(program: Program, logs: string[], programId?: string): Event[];
|
package/lib/events/parse.js
CHANGED
|
@@ -2,19 +2,18 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.parseLogs = void 0;
|
|
4
4
|
const driftProgramId = 'dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH';
|
|
5
|
-
const driftProgramStart = `Program ${driftProgramId} invoke`;
|
|
6
5
|
const PROGRAM_LOG = 'Program log: ';
|
|
7
6
|
const PROGRAM_DATA = 'Program data: ';
|
|
8
7
|
const PROGRAM_LOG_START_INDEX = PROGRAM_LOG.length;
|
|
9
8
|
const PROGRAM_DATA_START_INDEX = PROGRAM_DATA.length;
|
|
10
|
-
function parseLogs(program, logs) {
|
|
9
|
+
function parseLogs(program, logs, programId = driftProgramId) {
|
|
11
10
|
const events = [];
|
|
12
11
|
const execution = new ExecutionContext();
|
|
13
12
|
for (const log of logs) {
|
|
14
13
|
if (log.startsWith('Log truncated')) {
|
|
15
14
|
break;
|
|
16
15
|
}
|
|
17
|
-
const [event, newProgram, didPop] = handleLog(execution, log, program);
|
|
16
|
+
const [event, newProgram, didPop] = handleLog(execution, log, program, programId);
|
|
18
17
|
if (event) {
|
|
19
18
|
events.push(event);
|
|
20
19
|
}
|
|
@@ -28,18 +27,18 @@ function parseLogs(program, logs) {
|
|
|
28
27
|
return events;
|
|
29
28
|
}
|
|
30
29
|
exports.parseLogs = parseLogs;
|
|
31
|
-
function handleLog(execution, log, program) {
|
|
30
|
+
function handleLog(execution, log, program, programId = driftProgramId) {
|
|
32
31
|
// Executing program is drift program.
|
|
33
|
-
if (execution.stack.length > 0 && execution.program() ===
|
|
34
|
-
return handleProgramLog(log, program);
|
|
32
|
+
if (execution.stack.length > 0 && execution.program() === programId) {
|
|
33
|
+
return handleProgramLog(log, program, programId);
|
|
35
34
|
}
|
|
36
35
|
// Executing program is not drift program.
|
|
37
36
|
else {
|
|
38
|
-
return [null, ...handleSystemLog(log)];
|
|
37
|
+
return [null, ...handleSystemLog(log, programId)];
|
|
39
38
|
}
|
|
40
39
|
}
|
|
41
40
|
// Handles logs from *drift* program.
|
|
42
|
-
function handleProgramLog(log, program) {
|
|
41
|
+
function handleProgramLog(log, program, programId = driftProgramId) {
|
|
43
42
|
// This is a `msg!` log or a `sol_log_data` log.
|
|
44
43
|
if (log.startsWith(PROGRAM_LOG)) {
|
|
45
44
|
const logStr = log.slice(PROGRAM_LOG_START_INDEX);
|
|
@@ -52,20 +51,21 @@ function handleProgramLog(log, program) {
|
|
|
52
51
|
return [event, null, false];
|
|
53
52
|
}
|
|
54
53
|
else {
|
|
55
|
-
return [null, ...handleSystemLog(log)];
|
|
54
|
+
return [null, ...handleSystemLog(log, programId)];
|
|
56
55
|
}
|
|
57
56
|
}
|
|
58
57
|
// Handles logs when the current program being executing is *not* drift.
|
|
59
|
-
function handleSystemLog(log) {
|
|
58
|
+
function handleSystemLog(log, programId = driftProgramId) {
|
|
60
59
|
// System component.
|
|
61
60
|
const logStart = log.split(':')[0];
|
|
61
|
+
const programStart = `Program ${programId} invoke`;
|
|
62
62
|
// Did the program finish executing?
|
|
63
63
|
if (logStart.match(/^Program (.*) success/g) !== null) {
|
|
64
64
|
return [null, true];
|
|
65
65
|
// Recursive call.
|
|
66
66
|
}
|
|
67
|
-
else if (logStart.startsWith(
|
|
68
|
-
return [
|
|
67
|
+
else if (logStart.startsWith(programStart)) {
|
|
68
|
+
return [programId, false];
|
|
69
69
|
}
|
|
70
70
|
// CPI call.
|
|
71
71
|
else if (logStart.includes('invoke')) {
|
package/lib/idl/drift.json
CHANGED
|
@@ -2651,10 +2651,40 @@
|
|
|
2651
2651
|
"name": "liquidatorFee",
|
|
2652
2652
|
"type": "u32"
|
|
2653
2653
|
},
|
|
2654
|
+
{
|
|
2655
|
+
"name": "ifLiquidationFee",
|
|
2656
|
+
"type": "u32"
|
|
2657
|
+
},
|
|
2654
2658
|
{
|
|
2655
2659
|
"name": "activeStatus",
|
|
2656
2660
|
"type": "bool"
|
|
2657
2661
|
},
|
|
2662
|
+
{
|
|
2663
|
+
"name": "assetTier",
|
|
2664
|
+
"type": {
|
|
2665
|
+
"defined": "AssetTier"
|
|
2666
|
+
}
|
|
2667
|
+
},
|
|
2668
|
+
{
|
|
2669
|
+
"name": "scaleInitialAssetWeightStart",
|
|
2670
|
+
"type": "u64"
|
|
2671
|
+
},
|
|
2672
|
+
{
|
|
2673
|
+
"name": "withdrawGuardThreshold",
|
|
2674
|
+
"type": "u64"
|
|
2675
|
+
},
|
|
2676
|
+
{
|
|
2677
|
+
"name": "orderTickSize",
|
|
2678
|
+
"type": "u64"
|
|
2679
|
+
},
|
|
2680
|
+
{
|
|
2681
|
+
"name": "orderStepSize",
|
|
2682
|
+
"type": "u64"
|
|
2683
|
+
},
|
|
2684
|
+
{
|
|
2685
|
+
"name": "ifTotalFactor",
|
|
2686
|
+
"type": "u32"
|
|
2687
|
+
},
|
|
2658
2688
|
{
|
|
2659
2689
|
"name": "name",
|
|
2660
2690
|
"type": {
|
|
@@ -2943,10 +2973,62 @@
|
|
|
2943
2973
|
"name": "liquidatorFee",
|
|
2944
2974
|
"type": "u32"
|
|
2945
2975
|
},
|
|
2976
|
+
{
|
|
2977
|
+
"name": "ifLiquidationFee",
|
|
2978
|
+
"type": "u32"
|
|
2979
|
+
},
|
|
2980
|
+
{
|
|
2981
|
+
"name": "imfFactor",
|
|
2982
|
+
"type": "u32"
|
|
2983
|
+
},
|
|
2946
2984
|
{
|
|
2947
2985
|
"name": "activeStatus",
|
|
2948
2986
|
"type": "bool"
|
|
2949
2987
|
},
|
|
2988
|
+
{
|
|
2989
|
+
"name": "baseSpread",
|
|
2990
|
+
"type": "u32"
|
|
2991
|
+
},
|
|
2992
|
+
{
|
|
2993
|
+
"name": "maxSpread",
|
|
2994
|
+
"type": "u32"
|
|
2995
|
+
},
|
|
2996
|
+
{
|
|
2997
|
+
"name": "maxOpenInterest",
|
|
2998
|
+
"type": "u128"
|
|
2999
|
+
},
|
|
3000
|
+
{
|
|
3001
|
+
"name": "maxRevenueWithdrawPerPeriod",
|
|
3002
|
+
"type": "u64"
|
|
3003
|
+
},
|
|
3004
|
+
{
|
|
3005
|
+
"name": "quoteMaxInsurance",
|
|
3006
|
+
"type": "u64"
|
|
3007
|
+
},
|
|
3008
|
+
{
|
|
3009
|
+
"name": "orderStepSize",
|
|
3010
|
+
"type": "u64"
|
|
3011
|
+
},
|
|
3012
|
+
{
|
|
3013
|
+
"name": "orderTickSize",
|
|
3014
|
+
"type": "u64"
|
|
3015
|
+
},
|
|
3016
|
+
{
|
|
3017
|
+
"name": "minOrderSize",
|
|
3018
|
+
"type": "u64"
|
|
3019
|
+
},
|
|
3020
|
+
{
|
|
3021
|
+
"name": "concentrationCoefScale",
|
|
3022
|
+
"type": "u128"
|
|
3023
|
+
},
|
|
3024
|
+
{
|
|
3025
|
+
"name": "curveUpdateIntensity",
|
|
3026
|
+
"type": "u16"
|
|
3027
|
+
},
|
|
3028
|
+
{
|
|
3029
|
+
"name": "ammJitUpdateIntensity",
|
|
3030
|
+
"type": "u16"
|
|
3031
|
+
},
|
|
2950
3032
|
{
|
|
2951
3033
|
"name": "name",
|
|
2952
3034
|
"type": {
|
|
@@ -9119,6 +9201,9 @@
|
|
|
9119
9201
|
{
|
|
9120
9202
|
"name": "Speculative"
|
|
9121
9203
|
},
|
|
9204
|
+
{
|
|
9205
|
+
"name": "HighlySpeculative"
|
|
9206
|
+
},
|
|
9122
9207
|
{
|
|
9123
9208
|
"name": "Isolated"
|
|
9124
9209
|
}
|
|
@@ -11626,5 +11711,8 @@
|
|
|
11626
11711
|
"name": "CantReclaimRent",
|
|
11627
11712
|
"msg": "CantReclaimRent"
|
|
11628
11713
|
}
|
|
11629
|
-
]
|
|
11714
|
+
],
|
|
11715
|
+
"metadata": {
|
|
11716
|
+
"address": "dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH"
|
|
11717
|
+
}
|
|
11630
11718
|
}
|
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -121,3 +121,4 @@ __exportStar(require("./auctionSubscriber"), exports);
|
|
|
121
121
|
__exportStar(require("./auctionSubscriber/types"), exports);
|
|
122
122
|
__exportStar(require("./memcmp"), exports);
|
|
123
123
|
__exportStar(require("./decode/user"), exports);
|
|
124
|
+
__exportStar(require("./blockhashSubscriber"), exports);
|
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
|
@@ -27,6 +27,7 @@ export declare class PriorityFeeSubscriber {
|
|
|
27
27
|
private loadForHelius;
|
|
28
28
|
getMaxPriorityFee(): number | undefined;
|
|
29
29
|
updateMaxPriorityFee(newMaxFee: number | undefined): void;
|
|
30
|
+
updateCustomStrategy(newStrategy: PriorityFeeStrategy): void;
|
|
30
31
|
getHeliusPriorityFeeLevel(level?: HeliusPriorityLevel): number;
|
|
31
32
|
getCustomStrategyResult(): number;
|
|
32
33
|
getAvgStrategyResult(): number;
|
|
@@ -87,6 +87,9 @@ class PriorityFeeSubscriber {
|
|
|
87
87
|
updateMaxPriorityFee(newMaxFee) {
|
|
88
88
|
this.maxFeeMicroLamports = newMaxFee;
|
|
89
89
|
}
|
|
90
|
+
updateCustomStrategy(newStrategy) {
|
|
91
|
+
this.customStrategy = newStrategy;
|
|
92
|
+
}
|
|
90
93
|
getHeliusPriorityFeeLevel(level = heliusPriorityFeeMethod_1.HeliusPriorityLevel.MEDIUM) {
|
|
91
94
|
if (this.lastHeliusSample === undefined) {
|
|
92
95
|
return 0;
|
package/lib/tx/baseTxSender.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ export declare abstract class BaseTxSender implements TxSender {
|
|
|
22
22
|
});
|
|
23
23
|
send(tx: Transaction, additionalSigners?: Array<Signer>, opts?: ConfirmOptions, preSigned?: boolean, extraConfirmationOptions?: ExtraConfirmationOptions): Promise<TxSigAndSlot>;
|
|
24
24
|
prepareTx(tx: Transaction, additionalSigners: Array<Signer>, opts: ConfirmOptions): Promise<Transaction>;
|
|
25
|
-
getVersionedTransaction(ixs: TransactionInstruction[], lookupTableAccounts: AddressLookupTableAccount[], additionalSigners?: Array<Signer>, opts?: ConfirmOptions): Promise<VersionedTransaction>;
|
|
25
|
+
getVersionedTransaction(ixs: TransactionInstruction[], lookupTableAccounts: AddressLookupTableAccount[], additionalSigners?: Array<Signer>, opts?: ConfirmOptions, blockhash?: string): Promise<VersionedTransaction>;
|
|
26
26
|
sendVersionedTransaction(tx: VersionedTransaction, additionalSigners?: Array<Signer>, opts?: ConfirmOptions, preSigned?: boolean, extraConfirmationOptions?: ExtraConfirmationOptions): Promise<TxSigAndSlot>;
|
|
27
27
|
sendRawTransaction(rawTransaction: Buffer | Uint8Array, opts: ConfirmOptions): Promise<TxSigAndSlot>;
|
|
28
28
|
simulateTransaction(tx: VersionedTransaction): Promise<boolean>;
|