@drift-labs/sdk 2.17.0 → 2.18.0-beta.1
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/constants/perpMarkets.js +10 -0
- package/lib/dlob/DLOB.d.ts +32 -26
- package/lib/dlob/DLOB.js +246 -173
- package/lib/dlob/DLOBNode.d.ts +11 -5
- package/lib/dlob/DLOBNode.js +13 -5
- package/lib/driftClient.js +5 -10
- package/lib/examples/loadDlob.js +1 -1
- package/lib/factory/oracleClient.js +4 -0
- package/lib/idl/drift.json +4 -1
- package/lib/math/auction.d.ts +1 -0
- package/lib/math/auction.js +9 -2
- package/lib/math/orders.d.ts +2 -0
- package/lib/math/orders.js +11 -2
- package/lib/math/spotBalance.js +1 -1
- package/lib/math/trade.d.ts +6 -0
- package/lib/math/trade.js +6 -0
- package/lib/oracles/pythClient.d.ts +4 -3
- package/lib/oracles/pythClient.js +8 -7
- package/lib/types.d.ts +4 -1
- package/lib/types.js +1 -0
- package/lib/user.js +8 -9
- package/package.json +1 -1
- package/src/constants/perpMarkets.ts +10 -0
- package/src/dlob/DLOB.ts +387 -183
- package/src/dlob/DLOBNode.ts +20 -7
- package/src/driftClient.ts +5 -10
- package/src/examples/loadDlob.ts +1 -1
- package/src/factory/oracleClient.ts +5 -0
- package/src/idl/drift.json +4 -1
- package/src/math/auction.ts +13 -1
- package/src/math/orders.ts +14 -1
- package/src/math/spotBalance.ts +1 -1
- package/src/math/trade.ts +6 -0
- package/src/oracles/pythClient.ts +27 -8
- package/src/types.ts +2 -1
- package/src/user.ts +7 -8
- package/tests/dlob/test.ts +800 -82
package/lib/dlob/DLOBNode.d.ts
CHANGED
|
@@ -22,9 +22,14 @@ export declare abstract class OrderNode implements DLOBNode {
|
|
|
22
22
|
isBaseFilled(): boolean;
|
|
23
23
|
isVammNode(): boolean;
|
|
24
24
|
}
|
|
25
|
-
export declare class
|
|
26
|
-
next?:
|
|
27
|
-
previous?:
|
|
25
|
+
export declare class TakingLimitOrderNode extends OrderNode {
|
|
26
|
+
next?: TakingLimitOrderNode;
|
|
27
|
+
previous?: TakingLimitOrderNode;
|
|
28
|
+
getSortValue(order: Order): BN;
|
|
29
|
+
}
|
|
30
|
+
export declare class RestingLimitOrderNode extends OrderNode {
|
|
31
|
+
next?: RestingLimitOrderNode;
|
|
32
|
+
previous?: RestingLimitOrderNode;
|
|
28
33
|
getSortValue(order: Order): BN;
|
|
29
34
|
}
|
|
30
35
|
export declare class FloatingLimitOrderNode extends OrderNode {
|
|
@@ -43,10 +48,11 @@ export declare class TriggerOrderNode extends OrderNode {
|
|
|
43
48
|
getSortValue(order: Order): BN;
|
|
44
49
|
}
|
|
45
50
|
export declare type DLOBNodeMap = {
|
|
46
|
-
|
|
51
|
+
restingLimit: RestingLimitOrderNode;
|
|
52
|
+
takingLimit: TakingLimitOrderNode;
|
|
47
53
|
floatingLimit: FloatingLimitOrderNode;
|
|
48
54
|
market: MarketOrderNode;
|
|
49
55
|
trigger: TriggerOrderNode;
|
|
50
56
|
};
|
|
51
|
-
export declare type DLOBNodeType = '
|
|
57
|
+
export declare type DLOBNodeType = 'restingLimit' | 'takingLimit' | 'floatingLimit' | 'market' | ('trigger' & keyof DLOBNodeMap);
|
|
52
58
|
export declare function createNode<T extends DLOBNodeType>(nodeType: T, order: Order, userAccount: PublicKey): DLOBNodeMap[T];
|
package/lib/dlob/DLOBNode.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createNode = exports.TriggerOrderNode = exports.MarketOrderNode = exports.FloatingLimitOrderNode = exports.
|
|
3
|
+
exports.createNode = exports.TriggerOrderNode = exports.MarketOrderNode = exports.FloatingLimitOrderNode = exports.RestingLimitOrderNode = exports.TakingLimitOrderNode = exports.OrderNode = void 0;
|
|
4
4
|
const __1 = require("..");
|
|
5
5
|
const NodeList_1 = require("./NodeList");
|
|
6
6
|
class OrderNode {
|
|
@@ -36,12 +36,18 @@ class OrderNode {
|
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
exports.OrderNode = OrderNode;
|
|
39
|
-
class
|
|
39
|
+
class TakingLimitOrderNode extends OrderNode {
|
|
40
|
+
getSortValue(order) {
|
|
41
|
+
return order.slot;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
exports.TakingLimitOrderNode = TakingLimitOrderNode;
|
|
45
|
+
class RestingLimitOrderNode extends OrderNode {
|
|
40
46
|
getSortValue(order) {
|
|
41
47
|
return order.price;
|
|
42
48
|
}
|
|
43
49
|
}
|
|
44
|
-
exports.
|
|
50
|
+
exports.RestingLimitOrderNode = RestingLimitOrderNode;
|
|
45
51
|
class FloatingLimitOrderNode extends OrderNode {
|
|
46
52
|
getSortValue(order) {
|
|
47
53
|
return new __1.BN(order.oraclePriceOffset);
|
|
@@ -64,8 +70,10 @@ function createNode(nodeType, order, userAccount) {
|
|
|
64
70
|
switch (nodeType) {
|
|
65
71
|
case 'floatingLimit':
|
|
66
72
|
return new FloatingLimitOrderNode(order, userAccount);
|
|
67
|
-
case '
|
|
68
|
-
return new
|
|
73
|
+
case 'restingLimit':
|
|
74
|
+
return new RestingLimitOrderNode(order, userAccount);
|
|
75
|
+
case 'takingLimit':
|
|
76
|
+
return new TakingLimitOrderNode(order, userAccount);
|
|
69
77
|
case 'market':
|
|
70
78
|
return new MarketOrderNode(order, userAccount);
|
|
71
79
|
case 'trigger':
|
package/lib/driftClient.js
CHANGED
|
@@ -672,9 +672,8 @@ class DriftClient {
|
|
|
672
672
|
}
|
|
673
673
|
async deposit(amount, marketIndex, collateralAccountPublicKey, subAccountId, reduceOnly = false) {
|
|
674
674
|
const tx = new web3_js_1.Transaction();
|
|
675
|
-
tx.add(web3_js_1.ComputeBudgetProgram.
|
|
675
|
+
tx.add(web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
|
|
676
676
|
units: 600000,
|
|
677
|
-
additionalFee: 0,
|
|
678
677
|
}));
|
|
679
678
|
const additionalSigners = [];
|
|
680
679
|
const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
|
|
@@ -828,9 +827,8 @@ class DriftClient {
|
|
|
828
827
|
}
|
|
829
828
|
async withdraw(amount, marketIndex, userTokenAccount, reduceOnly = false) {
|
|
830
829
|
const tx = new web3_js_1.Transaction();
|
|
831
|
-
tx.add(web3_js_1.ComputeBudgetProgram.
|
|
830
|
+
tx.add(web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
|
|
832
831
|
units: 600000,
|
|
833
|
-
additionalFee: 0,
|
|
834
832
|
}));
|
|
835
833
|
const additionalSigners = [];
|
|
836
834
|
const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
|
|
@@ -1853,9 +1851,8 @@ class DriftClient {
|
|
|
1853
1851
|
? await this.getPlaceSpotOrderIx(newOrderParams)
|
|
1854
1852
|
: await this.getPlacePerpOrderIx(newOrderParams);
|
|
1855
1853
|
const tx = new web3_js_1.Transaction();
|
|
1856
|
-
tx.add(web3_js_1.ComputeBudgetProgram.
|
|
1854
|
+
tx.add(web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
|
|
1857
1855
|
units: 1000000,
|
|
1858
|
-
additionalFee: 0,
|
|
1859
1856
|
}));
|
|
1860
1857
|
tx.add(cancelOrderIx);
|
|
1861
1858
|
tx.add(placeOrderIx);
|
|
@@ -1929,9 +1926,8 @@ class DriftClient {
|
|
|
1929
1926
|
? await this.getPlaceSpotOrderIx(newOrderParams)
|
|
1930
1927
|
: await this.getPlacePerpOrderIx(newOrderParams);
|
|
1931
1928
|
const tx = new web3_js_1.Transaction();
|
|
1932
|
-
tx.add(web3_js_1.ComputeBudgetProgram.
|
|
1929
|
+
tx.add(web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
|
|
1933
1930
|
units: 1000000,
|
|
1934
|
-
additionalFee: 0,
|
|
1935
1931
|
}));
|
|
1936
1932
|
tx.add(cancelOrderIx);
|
|
1937
1933
|
tx.add(placeOrderIx);
|
|
@@ -1951,9 +1947,8 @@ class DriftClient {
|
|
|
1951
1947
|
ixs.push(await this.settlePNLIx(settleeUserAccountPublicKey, settleeUserAccount, marketIndex));
|
|
1952
1948
|
}
|
|
1953
1949
|
const tx = new web3_js_1.Transaction()
|
|
1954
|
-
.add(web3_js_1.ComputeBudgetProgram.
|
|
1950
|
+
.add(web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
|
|
1955
1951
|
units: 1000000,
|
|
1956
|
-
additionalFee: 0,
|
|
1957
1952
|
}))
|
|
1958
1953
|
.add(...ixs);
|
|
1959
1954
|
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
package/lib/examples/loadDlob.js
CHANGED
|
@@ -41,7 +41,7 @@ const main = async () => {
|
|
|
41
41
|
await userMap.fetchAllUsers();
|
|
42
42
|
console.log('Loading dlob from user map...');
|
|
43
43
|
const dlob = new __1.DLOB();
|
|
44
|
-
await dlob.initFromUserMap(userMap);
|
|
44
|
+
await dlob.initFromUserMap(userMap, bulkAccountLoader.mostRecentSlot);
|
|
45
45
|
console.log('number of orders', dlob.getDLOBOrders().length);
|
|
46
46
|
dlob.clear();
|
|
47
47
|
console.log('Unsubscribing users...');
|
|
@@ -5,10 +5,14 @@ const types_1 = require("../types");
|
|
|
5
5
|
const pythClient_1 = require("../oracles/pythClient");
|
|
6
6
|
// import { SwitchboardClient } from '../oracles/switchboardClient';
|
|
7
7
|
const quoteAssetOracleClient_1 = require("../oracles/quoteAssetOracleClient");
|
|
8
|
+
const anchor_1 = require("@project-serum/anchor");
|
|
8
9
|
function getOracleClient(oracleSource, connection) {
|
|
9
10
|
if (types_1.isVariant(oracleSource, 'pyth')) {
|
|
10
11
|
return new pythClient_1.PythClient(connection);
|
|
11
12
|
}
|
|
13
|
+
if (types_1.isVariant(oracleSource, 'pyth1000')) {
|
|
14
|
+
return new pythClient_1.PythClient(connection, new anchor_1.BN(1000));
|
|
15
|
+
}
|
|
12
16
|
// if (isVariant(oracleSource, 'switchboard')) {
|
|
13
17
|
// return new SwitchboardClient(connection);
|
|
14
18
|
// }
|
package/lib/idl/drift.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "2.
|
|
2
|
+
"version": "2.18.0-beta.1",
|
|
3
3
|
"name": "drift",
|
|
4
4
|
"instructions": [
|
|
5
5
|
{
|
|
@@ -6237,6 +6237,9 @@
|
|
|
6237
6237
|
{
|
|
6238
6238
|
"name": "Pyth"
|
|
6239
6239
|
},
|
|
6240
|
+
{
|
|
6241
|
+
"name": "Pyth1000"
|
|
6242
|
+
},
|
|
6240
6243
|
{
|
|
6241
6244
|
"name": "Switchboard"
|
|
6242
6245
|
},
|
package/lib/math/auction.d.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { Order } from '../types';
|
|
3
3
|
import { BN } from '../.';
|
|
4
4
|
export declare function isAuctionComplete(order: Order, slot: number): boolean;
|
|
5
|
+
export declare function isFallbackAvailableLiquiditySource(order: Order, minAuctionDuration: number, slot: number): boolean;
|
|
5
6
|
export declare function getAuctionPrice(order: Order, slot: number, oraclePrice: BN): BN;
|
|
6
7
|
export declare function getAuctionPriceForFixedAuction(order: Order, slot: number): BN;
|
|
7
8
|
export declare function getAuctionPriceForOracleOffsetAuction(order: Order, slot: number, oraclePrice: BN): BN;
|
package/lib/math/auction.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getAuctionPriceForOracleOffsetAuction = exports.getAuctionPriceForFixedAuction = exports.getAuctionPrice = exports.isAuctionComplete = void 0;
|
|
3
|
+
exports.getAuctionPriceForOracleOffsetAuction = exports.getAuctionPriceForFixedAuction = exports.getAuctionPrice = exports.isFallbackAvailableLiquiditySource = exports.isAuctionComplete = void 0;
|
|
4
4
|
const types_1 = require("../types");
|
|
5
5
|
const _1 = require("../.");
|
|
6
6
|
function isAuctionComplete(order, slot) {
|
|
@@ -10,8 +10,15 @@ function isAuctionComplete(order, slot) {
|
|
|
10
10
|
return new _1.BN(slot).sub(order.slot).gt(new _1.BN(order.auctionDuration));
|
|
11
11
|
}
|
|
12
12
|
exports.isAuctionComplete = isAuctionComplete;
|
|
13
|
+
function isFallbackAvailableLiquiditySource(order, minAuctionDuration, slot) {
|
|
14
|
+
if (minAuctionDuration === 0) {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
return new _1.BN(slot).sub(order.slot).gt(new _1.BN(minAuctionDuration));
|
|
18
|
+
}
|
|
19
|
+
exports.isFallbackAvailableLiquiditySource = isFallbackAvailableLiquiditySource;
|
|
13
20
|
function getAuctionPrice(order, slot, oraclePrice) {
|
|
14
|
-
if (types_1.isOneOfVariant(order.orderType, ['market', 'triggerMarket'])) {
|
|
21
|
+
if (types_1.isOneOfVariant(order.orderType, ['market', 'triggerMarket', 'limit'])) {
|
|
15
22
|
return getAuctionPriceForFixedAuction(order, slot);
|
|
16
23
|
}
|
|
17
24
|
else if (types_1.isVariant(order.orderType, 'oracle')) {
|
package/lib/math/orders.d.ts
CHANGED
|
@@ -18,3 +18,5 @@ export declare function isMarketOrder(order: Order): boolean;
|
|
|
18
18
|
export declare function isLimitOrder(order: Order): boolean;
|
|
19
19
|
export declare function mustBeTriggered(order: Order): boolean;
|
|
20
20
|
export declare function isTriggered(order: Order): boolean;
|
|
21
|
+
export declare function isRestingLimitOrder(order: Order, slot: number): boolean;
|
|
22
|
+
export declare function isTakingOrder(order: Order, slot: number): boolean;
|
package/lib/math/orders.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isTriggered = exports.mustBeTriggered = exports.isLimitOrder = exports.isMarketOrder = exports.isOrderExpired = exports.calculateBaseAssetAmountToFillUpToLimitPrice = exports.calculateBaseAssetAmountForAmmToFulfill = exports.isFillableByVAMM = exports.hasAuctionPrice = exports.hasLimitPrice = exports.getLimitPrice = exports.standardizeBaseAssetAmount = exports.isOrderReduceOnly = exports.isOrderRiskIncreasingInSameDirection = exports.isOrderRiskIncreasing = void 0;
|
|
3
|
+
exports.isTakingOrder = exports.isRestingLimitOrder = exports.isTriggered = exports.mustBeTriggered = exports.isLimitOrder = exports.isMarketOrder = exports.isOrderExpired = exports.calculateBaseAssetAmountToFillUpToLimitPrice = exports.calculateBaseAssetAmountForAmmToFulfill = exports.isFillableByVAMM = exports.hasAuctionPrice = exports.hasLimitPrice = exports.getLimitPrice = exports.standardizeBaseAssetAmount = exports.isOrderReduceOnly = exports.isOrderRiskIncreasingInSameDirection = exports.isOrderRiskIncreasing = void 0;
|
|
4
4
|
const types_1 = require("../types");
|
|
5
5
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
6
6
|
const anchor_1 = require("@project-serum/anchor");
|
|
@@ -103,7 +103,8 @@ function hasLimitPrice(order, slot) {
|
|
|
103
103
|
}
|
|
104
104
|
exports.hasLimitPrice = hasLimitPrice;
|
|
105
105
|
function hasAuctionPrice(order, slot) {
|
|
106
|
-
return
|
|
106
|
+
return (!auction_1.isAuctionComplete(order, slot) &&
|
|
107
|
+
(!order.auctionStartPrice.eq(numericConstants_1.ZERO) || !order.auctionEndPrice.eq(numericConstants_1.ZERO)));
|
|
107
108
|
}
|
|
108
109
|
exports.hasAuctionPrice = hasAuctionPrice;
|
|
109
110
|
function isFillableByVAMM(order, market, oraclePriceData, slot, ts) {
|
|
@@ -175,3 +176,11 @@ function isTriggered(order) {
|
|
|
175
176
|
]);
|
|
176
177
|
}
|
|
177
178
|
exports.isTriggered = isTriggered;
|
|
179
|
+
function isRestingLimitOrder(order, slot) {
|
|
180
|
+
return (isLimitOrder(order) && (order.postOnly || auction_1.isAuctionComplete(order, slot)));
|
|
181
|
+
}
|
|
182
|
+
exports.isRestingLimitOrder = isRestingLimitOrder;
|
|
183
|
+
function isTakingOrder(order, slot) {
|
|
184
|
+
return isMarketOrder(order) || !isRestingLimitOrder(order, slot);
|
|
185
|
+
}
|
|
186
|
+
exports.isTakingOrder = isTakingOrder;
|
package/lib/math/spotBalance.js
CHANGED
|
@@ -200,7 +200,7 @@ function calculateWithdrawLimit(spotMarket, now) {
|
|
|
200
200
|
.mul(sinceStart)
|
|
201
201
|
.add(marketDepositTokenAmount.mul(sinceLast))
|
|
202
202
|
.div(sinceLast.add(sinceStart));
|
|
203
|
-
const maxBorrowTokens = anchor_1.BN.max(spotMarket.withdrawGuardThreshold, anchor_1.BN.min(anchor_1.BN.max(marketDepositTokenAmount.div(new anchor_1.BN(6)), borrowTokenTwapLive.add(
|
|
203
|
+
const maxBorrowTokens = anchor_1.BN.max(spotMarket.withdrawGuardThreshold, anchor_1.BN.min(anchor_1.BN.max(marketDepositTokenAmount.div(new anchor_1.BN(6)), borrowTokenTwapLive.add(marketDepositTokenAmount.div(new anchor_1.BN(10)))), marketDepositTokenAmount.sub(marketDepositTokenAmount.div(new anchor_1.BN(5))))); // between ~15-80% utilization with friction on twap
|
|
204
204
|
const minDepositTokens = depositTokenTwapLive.sub(anchor_1.BN.max(depositTokenTwapLive.div(new anchor_1.BN(5)), anchor_1.BN.min(spotMarket.withdrawGuardThreshold, depositTokenTwapLive)));
|
|
205
205
|
let withdrawLimit = anchor_1.BN.max(marketDepositTokenAmount.sub(minDepositTokens), numericConstants_1.ZERO);
|
|
206
206
|
let borrowLimit = maxBorrowTokens.sub(marketBorrowTokenAmount);
|
package/lib/math/trade.d.ts
CHANGED
|
@@ -9,6 +9,9 @@ import { Orderbook } from '@project-serum/serum';
|
|
|
9
9
|
export declare type PriceImpactUnit = 'entryPrice' | 'maxPrice' | 'priceDelta' | 'priceDeltaAsNumber' | 'pctAvg' | 'pctMax' | 'quoteAssetAmount' | 'quoteAssetAmountPeg' | 'acquiredBaseAssetAmount' | 'acquiredQuoteAssetAmount' | 'all';
|
|
10
10
|
/**
|
|
11
11
|
* Calculates avg/max slippage (price impact) for candidate trade
|
|
12
|
+
*
|
|
13
|
+
* @deprecated use calculateEstimatedPerpEntryPrice instead
|
|
14
|
+
*
|
|
12
15
|
* @param direction
|
|
13
16
|
* @param amount
|
|
14
17
|
* @param market
|
|
@@ -40,6 +43,9 @@ export declare function calculateTradeAcquiredAmounts(direction: PositionDirecti
|
|
|
40
43
|
/**
|
|
41
44
|
* calculateTargetPriceTrade
|
|
42
45
|
* simple function for finding arbitraging trades
|
|
46
|
+
*
|
|
47
|
+
* @deprecated
|
|
48
|
+
*
|
|
43
49
|
* @param market
|
|
44
50
|
* @param targetPrice
|
|
45
51
|
* @param pct optional default is 100% gap filling, can set smaller.
|
package/lib/math/trade.js
CHANGED
|
@@ -12,6 +12,9 @@ const types_2 = require("../types");
|
|
|
12
12
|
const MAXPCT = new anchor_1.BN(1000); //percentage units are [0,1000] => [0,1]
|
|
13
13
|
/**
|
|
14
14
|
* Calculates avg/max slippage (price impact) for candidate trade
|
|
15
|
+
*
|
|
16
|
+
* @deprecated use calculateEstimatedPerpEntryPrice instead
|
|
17
|
+
*
|
|
15
18
|
* @param direction
|
|
16
19
|
* @param amount
|
|
17
20
|
* @param market
|
|
@@ -120,6 +123,9 @@ exports.calculateTradeAcquiredAmounts = calculateTradeAcquiredAmounts;
|
|
|
120
123
|
/**
|
|
121
124
|
* calculateTargetPriceTrade
|
|
122
125
|
* simple function for finding arbitraging trades
|
|
126
|
+
*
|
|
127
|
+
* @deprecated
|
|
128
|
+
*
|
|
123
129
|
* @param market
|
|
124
130
|
* @param targetPrice
|
|
125
131
|
* @param pct optional default is 100% gap filling, can set smaller.
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
1
|
/// <reference types="bn.js" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
3
|
import { Connection, PublicKey } from '@solana/web3.js';
|
|
4
4
|
import { OracleClient, OraclePriceData } from './types';
|
|
5
5
|
import { BN } from '@project-serum/anchor';
|
|
6
6
|
export declare class PythClient implements OracleClient {
|
|
7
7
|
private connection;
|
|
8
|
-
|
|
8
|
+
private multiple;
|
|
9
|
+
constructor(connection: Connection, multiple?: BN);
|
|
9
10
|
getOraclePriceData(pricePublicKey: PublicKey): Promise<OraclePriceData>;
|
|
10
11
|
getOraclePriceDataFromBuffer(buffer: Buffer): OraclePriceData;
|
|
11
12
|
}
|
|
12
|
-
export declare function convertPythPrice(price: number, exponent: number): BN;
|
|
13
|
+
export declare function convertPythPrice(price: number, exponent: number, multiple: BN): BN;
|
|
@@ -5,8 +5,9 @@ const client_1 = require("@pythnetwork/client");
|
|
|
5
5
|
const anchor_1 = require("@project-serum/anchor");
|
|
6
6
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
7
7
|
class PythClient {
|
|
8
|
-
constructor(connection) {
|
|
8
|
+
constructor(connection, multiple = numericConstants_1.ONE) {
|
|
9
9
|
this.connection = connection;
|
|
10
|
+
this.multiple = multiple;
|
|
10
11
|
}
|
|
11
12
|
async getOraclePriceData(pricePublicKey) {
|
|
12
13
|
const accountInfo = await this.connection.getAccountInfo(pricePublicKey);
|
|
@@ -15,19 +16,19 @@ class PythClient {
|
|
|
15
16
|
getOraclePriceDataFromBuffer(buffer) {
|
|
16
17
|
const priceData = client_1.parsePriceData(buffer);
|
|
17
18
|
return {
|
|
18
|
-
price: convertPythPrice(priceData.aggregate.price, priceData.exponent),
|
|
19
|
+
price: convertPythPrice(priceData.aggregate.price, priceData.exponent, this.multiple),
|
|
19
20
|
slot: new anchor_1.BN(priceData.lastSlot.toString()),
|
|
20
|
-
confidence: convertPythPrice(priceData.confidence, priceData.exponent),
|
|
21
|
-
twap: convertPythPrice(priceData.twap.value, priceData.exponent),
|
|
22
|
-
twapConfidence: convertPythPrice(priceData.twac.value, priceData.exponent),
|
|
21
|
+
confidence: convertPythPrice(priceData.confidence, priceData.exponent, this.multiple),
|
|
22
|
+
twap: convertPythPrice(priceData.twap.value, priceData.exponent, this.multiple),
|
|
23
|
+
twapConfidence: convertPythPrice(priceData.twac.value, priceData.exponent, this.multiple),
|
|
23
24
|
hasSufficientNumberOfDataPoints: true,
|
|
24
25
|
};
|
|
25
26
|
}
|
|
26
27
|
}
|
|
27
28
|
exports.PythClient = PythClient;
|
|
28
|
-
function convertPythPrice(price, exponent) {
|
|
29
|
+
function convertPythPrice(price, exponent, multiple) {
|
|
29
30
|
exponent = Math.abs(exponent);
|
|
30
|
-
const pythPrecision = numericConstants_1.TEN.pow(new anchor_1.BN(exponent).abs());
|
|
31
|
+
const pythPrecision = numericConstants_1.TEN.pow(new anchor_1.BN(exponent).abs()).div(multiple);
|
|
31
32
|
return new anchor_1.BN(price * Math.pow(10, exponent))
|
|
32
33
|
.mul(numericConstants_1.PRICE_PRECISION)
|
|
33
34
|
.div(pythPrecision);
|
package/lib/types.d.ts
CHANGED
|
@@ -130,6 +130,9 @@ export declare class OracleSource {
|
|
|
130
130
|
static readonly PYTH: {
|
|
131
131
|
pyth: {};
|
|
132
132
|
};
|
|
133
|
+
static readonly PYTH_1000: {
|
|
134
|
+
pyth1000: {};
|
|
135
|
+
};
|
|
133
136
|
static readonly QUOTE_ASSET: {
|
|
134
137
|
quoteAsset: {};
|
|
135
138
|
};
|
|
@@ -307,7 +310,7 @@ export declare type NewUserRecord = {
|
|
|
307
310
|
ts: BN;
|
|
308
311
|
userAuthority: PublicKey;
|
|
309
312
|
user: PublicKey;
|
|
310
|
-
|
|
313
|
+
subAccountId: number;
|
|
311
314
|
name: number[];
|
|
312
315
|
referrer: PublicKey;
|
|
313
316
|
};
|
package/lib/types.js
CHANGED
|
@@ -78,6 +78,7 @@ class OracleSource {
|
|
|
78
78
|
}
|
|
79
79
|
exports.OracleSource = OracleSource;
|
|
80
80
|
OracleSource.PYTH = { pyth: {} };
|
|
81
|
+
OracleSource.PYTH_1000 = { pyth1000: {} };
|
|
81
82
|
// static readonly SWITCHBOARD = { switchboard: {} };
|
|
82
83
|
OracleSource.QUOTE_ASSET = { quoteAsset: {} };
|
|
83
84
|
class OrderType {
|
package/lib/user.js
CHANGED
|
@@ -400,11 +400,13 @@ class User {
|
|
|
400
400
|
}
|
|
401
401
|
totalLiabilityValue = totalLiabilityValue.add(new _1.BN(spotPosition.openOrders).mul(numericConstants_1.OPEN_ORDER_MARGIN_REQUIREMENT));
|
|
402
402
|
}
|
|
403
|
-
if (
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
403
|
+
if (marketIndex === undefined || marketIndex === numericConstants_1.QUOTE_SPOT_MARKET_INDEX) {
|
|
404
|
+
if (netQuoteValue.gt(numericConstants_1.ZERO)) {
|
|
405
|
+
totalAssetValue = totalAssetValue.add(netQuoteValue);
|
|
406
|
+
}
|
|
407
|
+
else {
|
|
408
|
+
totalLiabilityValue = totalLiabilityValue.add(netQuoteValue.abs());
|
|
409
|
+
}
|
|
408
410
|
}
|
|
409
411
|
return { totalAssetValue, totalLiabilityValue };
|
|
410
412
|
}
|
|
@@ -994,10 +996,7 @@ class User {
|
|
|
994
996
|
// do nothing if targetting same side
|
|
995
997
|
}
|
|
996
998
|
}
|
|
997
|
-
|
|
998
|
-
// => to avoid rounding errors when taking max leverage
|
|
999
|
-
const oneMilli = maxPositionSize.div(numericConstants_1.QUOTE_PRECISION);
|
|
1000
|
-
return maxPositionSize.sub(oneMilli);
|
|
999
|
+
return maxPositionSize;
|
|
1001
1000
|
}
|
|
1002
1001
|
/**
|
|
1003
1002
|
* Get the maximum trade size for a given market, taking into account the user's current leverage, positions, collateral, etc.
|
package/package.json
CHANGED
|
@@ -54,6 +54,16 @@ export const DevnetPerpMarkets: PerpMarketConfig[] = [
|
|
|
54
54
|
launchTs: 1675610186000,
|
|
55
55
|
oracleSource: OracleSource.PYTH,
|
|
56
56
|
},
|
|
57
|
+
{
|
|
58
|
+
fullName: 'Bonk',
|
|
59
|
+
category: ['Meme'],
|
|
60
|
+
symbol: 'BONK-PERP',
|
|
61
|
+
baseAssetSymbol: 'BONK',
|
|
62
|
+
marketIndex: 4,
|
|
63
|
+
oracle: new PublicKey('6bquU99ktV1VRiHDr8gMhDFt3kMfhCQo5nfNrg2Urvsn'),
|
|
64
|
+
launchTs: 1677068931000,
|
|
65
|
+
oracleSource: OracleSource.PYTH_1000,
|
|
66
|
+
},
|
|
57
67
|
];
|
|
58
68
|
|
|
59
69
|
export const MainnetPerpMarkets: PerpMarketConfig[] = [
|