@drift-labs/sdk 0.1.29-master.1 → 0.1.29
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/clearingHouse.d.ts +4 -1
- package/lib/clearingHouse.js +49 -0
- package/lib/constants/markets.js +11 -0
- package/lib/idl/clearing_house.json +51 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/math/amm.d.ts +0 -2
- package/lib/math/amm.js +1 -64
- package/lib/oracles/pythClient.js +1 -1
- package/lib/orderParams.d.ts +1 -1
- package/lib/orderParams.js +2 -2
- package/package.json +1 -1
- package/src/clearingHouse.ts +71 -0
- package/src/constants/markets.ts +11 -0
- package/src/idl/clearing_house.json +51 -0
- package/src/index.ts +1 -0
- package/src/math/amm.ts +0 -86
- package/src/oracles/pythClient.ts +1 -1
- package/src/orderParams.ts +3 -2
- package/src/accounts/bulkUserSubscription.js +0 -56
- package/src/accounts/bulkUserSubscription.js.map +0 -1
- package/src/accounts/pollingUserAccountSubscriber.js +0 -139
- package/src/accounts/pollingUserAccountSubscriber.js.map +0 -1
- package/src/accounts/types.js +0 -11
- package/src/accounts/types.js.map +0 -1
- package/src/accounts/webSocketUserAccountSubscriber.js +0 -78
- package/src/accounts/webSocketUserAccountSubscriber.js.map +0 -1
- package/src/factory/clearingHouse.js +0 -65
- package/src/factory/clearingHouse.js.map +0 -1
- package/src/factory/clearingHouseUser.js +0 -35
- package/src/factory/clearingHouseUser.js.map +0 -1
- package/src/factory/oracleClient.js +0 -17
- package/src/factory/oracleClient.js.map +0 -1
- package/src/math/amm.js +0 -285
- package/src/math/amm.js.map +0 -1
- package/src/oracles/pythClient.js +0 -39
- package/src/oracles/pythClient.js.map +0 -1
package/lib/clearingHouse.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
/// <reference types="bn.js" />
|
|
3
3
|
import { BN, Program, Provider } from '@project-serum/anchor';
|
|
4
|
-
import { MarketsAccount, StateAccount, DepositHistoryAccount, FundingPaymentHistoryAccount, FundingRateHistoryAccount, IWallet, LiquidationHistoryAccount, PositionDirection, TradeHistoryAccount, UserAccount, Market, OrderHistoryAccount, OrderStateAccount, OrderParams, Order, ExtendedCurveHistoryAccount } from './types';
|
|
4
|
+
import { MarketsAccount, StateAccount, DepositHistoryAccount, FundingPaymentHistoryAccount, FundingRateHistoryAccount, IWallet, LiquidationHistoryAccount, PositionDirection, TradeHistoryAccount, UserAccount, Market, OrderHistoryAccount, OrderStateAccount, OrderParams, Order, ExtendedCurveHistoryAccount, UserPositionsAccount } from './types';
|
|
5
5
|
import { Connection, PublicKey, TransactionSignature, Keypair, ConfirmOptions, TransactionInstruction } from '@solana/web3.js';
|
|
6
6
|
import { MockUSDCFaucet } from './mockUSDCFaucet';
|
|
7
7
|
import { EventEmitter } from 'events';
|
|
@@ -127,6 +127,8 @@ export declare class ClearingHouse {
|
|
|
127
127
|
getCancelOrderIx(orderId: BN, oracle?: PublicKey): Promise<TransactionInstruction>;
|
|
128
128
|
cancelOrderByUserId(userOrderId: number, oracle?: PublicKey): Promise<TransactionSignature>;
|
|
129
129
|
getCancelOrderByUserIdIx(userOrderId: number, oracle?: PublicKey): Promise<TransactionInstruction>;
|
|
130
|
+
cancelAllOrders(oracles?: PublicKey[]): Promise<TransactionSignature>;
|
|
131
|
+
getCancelAllOrdersIx(oracles: PublicKey[]): Promise<TransactionInstruction>;
|
|
130
132
|
fillOrder(userAccountPublicKey: PublicKey, userOrdersAccountPublicKey: PublicKey, order: Order): Promise<TransactionSignature>;
|
|
131
133
|
getFillOrderIx(userAccountPublicKey: PublicKey, userOrdersAccountPublicKey: PublicKey, order: Order): Promise<TransactionInstruction>;
|
|
132
134
|
initializeUserOrdersThenPlaceAndFillOrder(orderParams: OrderParams, discountToken?: PublicKey, referrer?: PublicKey): Promise<TransactionSignature>;
|
|
@@ -141,6 +143,7 @@ export declare class ClearingHouse {
|
|
|
141
143
|
*/
|
|
142
144
|
closePosition(marketIndex: BN, discountToken?: PublicKey, referrer?: PublicKey): Promise<TransactionSignature>;
|
|
143
145
|
getClosePositionIx(marketIndex: BN, discountToken?: PublicKey, referrer?: PublicKey): Promise<TransactionInstruction>;
|
|
146
|
+
closeAllPositions(userPositionsAccount: UserPositionsAccount, discountToken?: PublicKey, referrer?: PublicKey): Promise<TransactionSignature>;
|
|
144
147
|
liquidate(liquidateeUserAccountPublicKey: PublicKey): Promise<TransactionSignature>;
|
|
145
148
|
getLiquidateIx(liquidateeUserAccountPublicKey: PublicKey): Promise<TransactionInstruction>;
|
|
146
149
|
updateFundingRate(oracle: PublicKey, marketIndex: BN): Promise<TransactionSignature>;
|
package/lib/clearingHouse.js
CHANGED
|
@@ -634,6 +634,42 @@ class ClearingHouse {
|
|
|
634
634
|
});
|
|
635
635
|
});
|
|
636
636
|
}
|
|
637
|
+
cancelAllOrders(oracles) {
|
|
638
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
639
|
+
return yield this.txSender.send((0, utils_1.wrapInTx)(yield this.getCancelAllOrdersIx(oracles)), [], this.opts);
|
|
640
|
+
});
|
|
641
|
+
}
|
|
642
|
+
getCancelAllOrdersIx(oracles) {
|
|
643
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
644
|
+
const userAccountPublicKey = yield this.getUserAccountPublicKey();
|
|
645
|
+
const userAccount = yield this.getUserAccount();
|
|
646
|
+
const state = this.getStateAccount();
|
|
647
|
+
const orderState = this.getOrderStateAccount();
|
|
648
|
+
const remainingAccounts = [];
|
|
649
|
+
for (const oracle of oracles) {
|
|
650
|
+
remainingAccounts.push({
|
|
651
|
+
pubkey: oracle,
|
|
652
|
+
isWritable: false,
|
|
653
|
+
isSigner: false,
|
|
654
|
+
});
|
|
655
|
+
}
|
|
656
|
+
return yield this.program.instruction.cancelAllOrders({
|
|
657
|
+
accounts: {
|
|
658
|
+
state: yield this.getStatePublicKey(),
|
|
659
|
+
user: userAccountPublicKey,
|
|
660
|
+
authority: this.wallet.publicKey,
|
|
661
|
+
markets: state.markets,
|
|
662
|
+
userOrders: yield this.getUserOrdersAccountPublicKey(),
|
|
663
|
+
userPositions: userAccount.positions,
|
|
664
|
+
fundingPaymentHistory: state.fundingPaymentHistory,
|
|
665
|
+
fundingRateHistory: state.fundingRateHistory,
|
|
666
|
+
orderState: yield this.getOrderStatePublicKey(),
|
|
667
|
+
orderHistory: orderState.orderHistory,
|
|
668
|
+
},
|
|
669
|
+
remainingAccounts,
|
|
670
|
+
});
|
|
671
|
+
});
|
|
672
|
+
}
|
|
637
673
|
fillOrder(userAccountPublicKey, userOrdersAccountPublicKey, order) {
|
|
638
674
|
return __awaiter(this, void 0, void 0, function* () {
|
|
639
675
|
return yield this.txSender.send((0, utils_1.wrapInTx)(yield this.getFillOrderIx(userAccountPublicKey, userOrdersAccountPublicKey, order)), [], this.opts);
|
|
@@ -801,6 +837,19 @@ class ClearingHouse {
|
|
|
801
837
|
});
|
|
802
838
|
});
|
|
803
839
|
}
|
|
840
|
+
closeAllPositions(userPositionsAccount, discountToken, referrer) {
|
|
841
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
842
|
+
const ixs = [];
|
|
843
|
+
for (const userPosition of userPositionsAccount.positions) {
|
|
844
|
+
if (userPosition.baseAssetAmount.eq(numericConstants_1.ZERO)) {
|
|
845
|
+
continue;
|
|
846
|
+
}
|
|
847
|
+
ixs.push(yield this.getClosePositionIx(userPosition.marketIndex, discountToken, referrer));
|
|
848
|
+
}
|
|
849
|
+
const tx = new web3_js_1.Transaction().add(...ixs);
|
|
850
|
+
return this.txSender.send(tx, [], this.opts);
|
|
851
|
+
});
|
|
852
|
+
}
|
|
804
853
|
liquidate(liquidateeUserAccountPublicKey) {
|
|
805
854
|
return __awaiter(this, void 0, void 0, function* () {
|
|
806
855
|
return this.txSender.send((0, utils_1.wrapInTx)(yield this.getLiquidateIx(liquidateeUserAccountPublicKey)), [], this.opts);
|
package/lib/constants/markets.js
CHANGED
|
@@ -177,6 +177,17 @@ exports.Markets = [
|
|
|
177
177
|
launchTs: 1648607439000,
|
|
178
178
|
oracleSource: __1.OracleSource.PYTH,
|
|
179
179
|
},
|
|
180
|
+
{
|
|
181
|
+
fullName: 'Near',
|
|
182
|
+
category: ['L1', 'Infra'],
|
|
183
|
+
symbol: 'NEAR-PERP',
|
|
184
|
+
baseAssetSymbol: 'NEAR',
|
|
185
|
+
marketIndex: new __1.BN(16),
|
|
186
|
+
devnetPublicKey: '3gnSbT7bhoTdGkFVZc1dW1PvjreWzpUNUD5ppXwv1N59',
|
|
187
|
+
mainnetPublicKey: 'ECSFWQ1bnnpqPVvoy9237t2wddZAaHisW88mYxuEHKWf',
|
|
188
|
+
launchTs: 1649105516000,
|
|
189
|
+
oracleSource: __1.OracleSource.PYTH,
|
|
190
|
+
},
|
|
180
191
|
// {
|
|
181
192
|
// symbol: 'mSOL-PERP',
|
|
182
193
|
// baseAssetSymbol: 'mSOL',
|
|
@@ -677,6 +677,57 @@
|
|
|
677
677
|
}
|
|
678
678
|
]
|
|
679
679
|
},
|
|
680
|
+
{
|
|
681
|
+
"name": "cancelAllOrders",
|
|
682
|
+
"accounts": [
|
|
683
|
+
{
|
|
684
|
+
"name": "state",
|
|
685
|
+
"isMut": false,
|
|
686
|
+
"isSigner": false
|
|
687
|
+
},
|
|
688
|
+
{
|
|
689
|
+
"name": "orderState",
|
|
690
|
+
"isMut": false,
|
|
691
|
+
"isSigner": false
|
|
692
|
+
},
|
|
693
|
+
{
|
|
694
|
+
"name": "user",
|
|
695
|
+
"isMut": false,
|
|
696
|
+
"isSigner": false
|
|
697
|
+
},
|
|
698
|
+
{
|
|
699
|
+
"name": "authority",
|
|
700
|
+
"isMut": false,
|
|
701
|
+
"isSigner": true
|
|
702
|
+
},
|
|
703
|
+
{
|
|
704
|
+
"name": "markets",
|
|
705
|
+
"isMut": false,
|
|
706
|
+
"isSigner": false
|
|
707
|
+
},
|
|
708
|
+
{
|
|
709
|
+
"name": "userPositions",
|
|
710
|
+
"isMut": true,
|
|
711
|
+
"isSigner": false
|
|
712
|
+
},
|
|
713
|
+
{
|
|
714
|
+
"name": "userOrders",
|
|
715
|
+
"isMut": true,
|
|
716
|
+
"isSigner": false
|
|
717
|
+
},
|
|
718
|
+
{
|
|
719
|
+
"name": "fundingPaymentHistory",
|
|
720
|
+
"isMut": true,
|
|
721
|
+
"isSigner": false
|
|
722
|
+
},
|
|
723
|
+
{
|
|
724
|
+
"name": "orderHistory",
|
|
725
|
+
"isMut": true,
|
|
726
|
+
"isSigner": false
|
|
727
|
+
}
|
|
728
|
+
],
|
|
729
|
+
"args": []
|
|
730
|
+
},
|
|
680
731
|
{
|
|
681
732
|
"name": "expireOrders",
|
|
682
733
|
"accounts": [
|
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -47,6 +47,7 @@ __exportStar(require("./math/position"), exports);
|
|
|
47
47
|
__exportStar(require("./math/amm"), exports);
|
|
48
48
|
__exportStar(require("./math/trade"), exports);
|
|
49
49
|
__exportStar(require("./math/orders"), exports);
|
|
50
|
+
__exportStar(require("./math/repeg"), exports);
|
|
50
51
|
__exportStar(require("./orders"), exports);
|
|
51
52
|
__exportStar(require("./orderParams"), exports);
|
|
52
53
|
__exportStar(require("./wallet"), exports);
|
package/lib/math/amm.d.ts
CHANGED
|
@@ -46,5 +46,3 @@ export declare function getSwapDirection(inputAssetType: AssetType, positionDire
|
|
|
46
46
|
*/
|
|
47
47
|
export declare function calculateTerminalPrice(market: Market): BN;
|
|
48
48
|
export declare function calculateMaxBaseAssetAmountToTrade(amm: AMM, limit_price: BN): [BN, PositionDirection];
|
|
49
|
-
export declare function calculateBudgetedK(market: Market, cost: BN): [BN, BN];
|
|
50
|
-
export declare function calculateBudgetedPeg(market: Market, cost: BN): BN;
|
package/lib/math/amm.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.calculateMaxBaseAssetAmountToTrade = exports.calculateTerminalPrice = exports.getSwapDirection = exports.calculateSwapOutput = exports.calculateAmmReservesAfterSwap = exports.calculatePrice = void 0;
|
|
4
4
|
const anchor_1 = require("@project-serum/anchor");
|
|
5
5
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
6
6
|
const types_1 = require("../types");
|
|
@@ -132,66 +132,3 @@ function calculateMaxBaseAssetAmountToTrade(amm, limit_price) {
|
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
exports.calculateMaxBaseAssetAmountToTrade = calculateMaxBaseAssetAmountToTrade;
|
|
135
|
-
function calculateBudgetedK(market, cost) {
|
|
136
|
-
// wolframalpha.com
|
|
137
|
-
// (1/(x+d) - p/(x*p+d))*y*d*Q = C solve for p
|
|
138
|
-
// p = (d(y*d*Q - C(x+d))) / (C*x(x+d) + y*y*d*Q)
|
|
139
|
-
// todo: assumes k = x * y
|
|
140
|
-
// otherwise use: (y(1-p) + (kp^2/(x*p+d)) - k/(x+d)) * Q = C solve for p
|
|
141
|
-
// const k = market.amm.sqrtK.mul(market.amm.sqrtK);
|
|
142
|
-
const x = market.amm.baseAssetReserve;
|
|
143
|
-
const y = market.amm.quoteAssetReserve;
|
|
144
|
-
const d = market.baseAssetAmount;
|
|
145
|
-
const Q = market.amm.pegMultiplier;
|
|
146
|
-
const C = cost.mul(new anchor_1.BN(-1));
|
|
147
|
-
const numer1 = y.mul(d).mul(Q).div(numericConstants_1.AMM_RESERVE_PRECISION).div(numericConstants_1.PEG_PRECISION);
|
|
148
|
-
const numer2 = C.mul(x.add(d)).div(numericConstants_1.QUOTE_PRECISION);
|
|
149
|
-
const denom1 = C.mul(x)
|
|
150
|
-
.mul(x.add(d))
|
|
151
|
-
.div(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
152
|
-
.div(numericConstants_1.QUOTE_PRECISION);
|
|
153
|
-
const denom2 = y
|
|
154
|
-
.mul(d)
|
|
155
|
-
.mul(d)
|
|
156
|
-
.mul(Q)
|
|
157
|
-
.div(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
158
|
-
.div(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
159
|
-
.div(numericConstants_1.PEG_PRECISION);
|
|
160
|
-
const numerator = d
|
|
161
|
-
.mul(numer1.add(numer2))
|
|
162
|
-
.div(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
163
|
-
.div(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
164
|
-
.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO);
|
|
165
|
-
const denominator = denom1
|
|
166
|
-
.add(denom2)
|
|
167
|
-
.div(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
168
|
-
.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO);
|
|
169
|
-
console.log(numerator, denominator);
|
|
170
|
-
// const p = (numerator).div(denominator);
|
|
171
|
-
// const formulaCost = (numer21.sub(numer20).sub(numer1)).mul(market.amm.pegMultiplier).div(AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO)
|
|
172
|
-
// console.log(convertToNumber(formulaCost, QUOTE_PRECISION))
|
|
173
|
-
return [numerator, denominator];
|
|
174
|
-
}
|
|
175
|
-
exports.calculateBudgetedK = calculateBudgetedK;
|
|
176
|
-
function calculateBudgetedPeg(market, cost) {
|
|
177
|
-
// wolframalpha.com
|
|
178
|
-
// (1/(x+d) - p/(x*p+d))*y*d*Q = C solve for p
|
|
179
|
-
// p = (d(y*d*Q - C(x+d))) / (C*x(x+d) + y*y*d*Q)
|
|
180
|
-
// todo: assumes k = x * y
|
|
181
|
-
// otherwise use: (y(1-p) + (kp^2/(x*p+d)) - k/(x+d)) * Q = C solve for p
|
|
182
|
-
const k = market.amm.sqrtK.mul(market.amm.sqrtK);
|
|
183
|
-
const x = market.amm.baseAssetReserve;
|
|
184
|
-
const y = market.amm.quoteAssetReserve;
|
|
185
|
-
const d = market.baseAssetAmount;
|
|
186
|
-
const Q = market.amm.pegMultiplier;
|
|
187
|
-
const C = cost.mul(new anchor_1.BN(-1));
|
|
188
|
-
const deltaQuoteAssetReserves = y.sub(k.div(x.add(d)));
|
|
189
|
-
const deltaPegMultiplier = C.mul(numericConstants_1.MARK_PRICE_PRECISION)
|
|
190
|
-
.div(deltaQuoteAssetReserves.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO))
|
|
191
|
-
.mul(numericConstants_1.PEG_PRECISION)
|
|
192
|
-
.div(numericConstants_1.QUOTE_PRECISION);
|
|
193
|
-
console.log(Q.toNumber(), 'change by', deltaPegMultiplier.toNumber() / numericConstants_1.MARK_PRICE_PRECISION.toNumber());
|
|
194
|
-
const newPeg = Q.sub(deltaPegMultiplier.mul(numericConstants_1.PEG_PRECISION).div(numericConstants_1.MARK_PRICE_PRECISION));
|
|
195
|
-
return newPeg;
|
|
196
|
-
}
|
|
197
|
-
exports.calculateBudgetedPeg = calculateBudgetedPeg;
|
|
@@ -33,7 +33,7 @@ class PythClient {
|
|
|
33
33
|
return __awaiter(this, void 0, void 0, function* () {
|
|
34
34
|
const priceData = (0, client_1.parsePriceData)(buffer);
|
|
35
35
|
return {
|
|
36
|
-
price: convertPythPrice(priceData.price, priceData.exponent),
|
|
36
|
+
price: convertPythPrice(priceData.aggregate.price, priceData.exponent),
|
|
37
37
|
slot: new anchor_1.BN(priceData.lastSlot.toString()),
|
|
38
38
|
confidence: convertPythPrice(priceData.confidence, priceData.exponent),
|
|
39
39
|
twap: convertPythPrice(priceData.twap.value, priceData.exponent),
|
package/lib/orderParams.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/// <reference types="bn.js" />
|
|
2
2
|
import { OrderParams, OrderTriggerCondition, PositionDirection } from './types';
|
|
3
3
|
import { BN } from '@project-serum/anchor';
|
|
4
|
-
export declare function getLimitOrderParams(marketIndex: BN, direction: PositionDirection, baseAssetAmount: BN, price: BN, reduceOnly: boolean, discountToken?: boolean, referrer?: boolean, userOrderId?: number, postOnly?: boolean, oraclePriceOffset?: BN): OrderParams;
|
|
4
|
+
export declare function getLimitOrderParams(marketIndex: BN, direction: PositionDirection, baseAssetAmount: BN, price: BN, reduceOnly: boolean, discountToken?: boolean, referrer?: boolean, userOrderId?: number, postOnly?: boolean, oraclePriceOffset?: BN, immediateOrCancel?: boolean): OrderParams;
|
|
5
5
|
export declare function getTriggerMarketOrderParams(marketIndex: BN, direction: PositionDirection, baseAssetAmount: BN, triggerPrice: BN, triggerCondition: OrderTriggerCondition, reduceOnly: boolean, discountToken?: boolean, referrer?: boolean, userOrderId?: number): OrderParams;
|
|
6
6
|
export declare function getTriggerLimitOrderParams(marketIndex: BN, direction: PositionDirection, baseAssetAmount: BN, price: BN, triggerPrice: BN, triggerCondition: OrderTriggerCondition, reduceOnly: boolean, discountToken?: boolean, referrer?: boolean, userOrderId?: number): OrderParams;
|
|
7
7
|
export declare function getMarketOrderParams(marketIndex: BN, direction: PositionDirection, quoteAssetAmount: BN, baseAssetAmount: BN, reduceOnly: boolean, price?: BN, discountToken?: boolean, referrer?: boolean): OrderParams;
|
package/lib/orderParams.js
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getMarketOrderParams = exports.getTriggerLimitOrderParams = exports.getTriggerMarketOrderParams = exports.getLimitOrderParams = void 0;
|
|
4
4
|
const types_1 = require("./types");
|
|
5
5
|
const numericConstants_1 = require("./constants/numericConstants");
|
|
6
|
-
function getLimitOrderParams(marketIndex, direction, baseAssetAmount, price, reduceOnly, discountToken = false, referrer = false, userOrderId = 0, postOnly = false, oraclePriceOffset = numericConstants_1.ZERO) {
|
|
6
|
+
function getLimitOrderParams(marketIndex, direction, baseAssetAmount, price, reduceOnly, discountToken = false, referrer = false, userOrderId = 0, postOnly = false, oraclePriceOffset = numericConstants_1.ZERO, immediateOrCancel = false) {
|
|
7
7
|
return {
|
|
8
8
|
orderType: types_1.OrderType.LIMIT,
|
|
9
9
|
userOrderId,
|
|
@@ -14,7 +14,7 @@ function getLimitOrderParams(marketIndex, direction, baseAssetAmount, price, red
|
|
|
14
14
|
price,
|
|
15
15
|
reduceOnly,
|
|
16
16
|
postOnly,
|
|
17
|
-
immediateOrCancel
|
|
17
|
+
immediateOrCancel,
|
|
18
18
|
positionLimit: numericConstants_1.ZERO,
|
|
19
19
|
padding0: true,
|
|
20
20
|
padding1: numericConstants_1.ZERO,
|
package/package.json
CHANGED
package/src/clearingHouse.ts
CHANGED
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
OrderParams,
|
|
22
22
|
Order,
|
|
23
23
|
ExtendedCurveHistoryAccount,
|
|
24
|
+
UserPositionsAccount,
|
|
24
25
|
} from './types';
|
|
25
26
|
import * as anchor from '@project-serum/anchor';
|
|
26
27
|
import clearingHouseIDL from './idl/clearing_house.json';
|
|
@@ -922,6 +923,51 @@ export class ClearingHouse {
|
|
|
922
923
|
});
|
|
923
924
|
}
|
|
924
925
|
|
|
926
|
+
public async cancelAllOrders(
|
|
927
|
+
oracles?: PublicKey[]
|
|
928
|
+
): Promise<TransactionSignature> {
|
|
929
|
+
return await this.txSender.send(
|
|
930
|
+
wrapInTx(await this.getCancelAllOrdersIx(oracles)),
|
|
931
|
+
[],
|
|
932
|
+
this.opts
|
|
933
|
+
);
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
public async getCancelAllOrdersIx(
|
|
937
|
+
oracles: PublicKey[]
|
|
938
|
+
): Promise<TransactionInstruction> {
|
|
939
|
+
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
940
|
+
const userAccount = await this.getUserAccount();
|
|
941
|
+
|
|
942
|
+
const state = this.getStateAccount();
|
|
943
|
+
const orderState = this.getOrderStateAccount();
|
|
944
|
+
|
|
945
|
+
const remainingAccounts = [];
|
|
946
|
+
for (const oracle of oracles) {
|
|
947
|
+
remainingAccounts.push({
|
|
948
|
+
pubkey: oracle,
|
|
949
|
+
isWritable: false,
|
|
950
|
+
isSigner: false,
|
|
951
|
+
});
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
return await this.program.instruction.cancelAllOrders({
|
|
955
|
+
accounts: {
|
|
956
|
+
state: await this.getStatePublicKey(),
|
|
957
|
+
user: userAccountPublicKey,
|
|
958
|
+
authority: this.wallet.publicKey,
|
|
959
|
+
markets: state.markets,
|
|
960
|
+
userOrders: await this.getUserOrdersAccountPublicKey(),
|
|
961
|
+
userPositions: userAccount.positions,
|
|
962
|
+
fundingPaymentHistory: state.fundingPaymentHistory,
|
|
963
|
+
fundingRateHistory: state.fundingRateHistory,
|
|
964
|
+
orderState: await this.getOrderStatePublicKey(),
|
|
965
|
+
orderHistory: orderState.orderHistory,
|
|
966
|
+
},
|
|
967
|
+
remainingAccounts,
|
|
968
|
+
});
|
|
969
|
+
}
|
|
970
|
+
|
|
925
971
|
public async fillOrder(
|
|
926
972
|
userAccountPublicKey: PublicKey,
|
|
927
973
|
userOrdersAccountPublicKey: PublicKey,
|
|
@@ -1160,6 +1206,31 @@ export class ClearingHouse {
|
|
|
1160
1206
|
);
|
|
1161
1207
|
}
|
|
1162
1208
|
|
|
1209
|
+
public async closeAllPositions(
|
|
1210
|
+
userPositionsAccount: UserPositionsAccount,
|
|
1211
|
+
discountToken?: PublicKey,
|
|
1212
|
+
referrer?: PublicKey
|
|
1213
|
+
): Promise<TransactionSignature> {
|
|
1214
|
+
const ixs: TransactionInstruction[] = [];
|
|
1215
|
+
for (const userPosition of userPositionsAccount.positions) {
|
|
1216
|
+
if (userPosition.baseAssetAmount.eq(ZERO)) {
|
|
1217
|
+
continue;
|
|
1218
|
+
}
|
|
1219
|
+
|
|
1220
|
+
ixs.push(
|
|
1221
|
+
await this.getClosePositionIx(
|
|
1222
|
+
userPosition.marketIndex,
|
|
1223
|
+
discountToken,
|
|
1224
|
+
referrer
|
|
1225
|
+
)
|
|
1226
|
+
);
|
|
1227
|
+
}
|
|
1228
|
+
|
|
1229
|
+
const tx = new Transaction().add(...ixs);
|
|
1230
|
+
|
|
1231
|
+
return this.txSender.send(tx, [], this.opts);
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1163
1234
|
public async liquidate(
|
|
1164
1235
|
liquidateeUserAccountPublicKey: PublicKey
|
|
1165
1236
|
): Promise<TransactionSignature> {
|
package/src/constants/markets.ts
CHANGED
|
@@ -187,6 +187,17 @@ export const Markets: MarketConfig[] = [
|
|
|
187
187
|
launchTs: 1648607439000,
|
|
188
188
|
oracleSource: OracleSource.PYTH,
|
|
189
189
|
},
|
|
190
|
+
{
|
|
191
|
+
fullName: 'Near',
|
|
192
|
+
category: ['L1', 'Infra'],
|
|
193
|
+
symbol: 'NEAR-PERP',
|
|
194
|
+
baseAssetSymbol: 'NEAR',
|
|
195
|
+
marketIndex: new BN(16),
|
|
196
|
+
devnetPublicKey: '3gnSbT7bhoTdGkFVZc1dW1PvjreWzpUNUD5ppXwv1N59',
|
|
197
|
+
mainnetPublicKey: 'ECSFWQ1bnnpqPVvoy9237t2wddZAaHisW88mYxuEHKWf',
|
|
198
|
+
launchTs: 1649105516000,
|
|
199
|
+
oracleSource: OracleSource.PYTH,
|
|
200
|
+
},
|
|
190
201
|
// {
|
|
191
202
|
// symbol: 'mSOL-PERP',
|
|
192
203
|
// baseAssetSymbol: 'mSOL',
|
|
@@ -677,6 +677,57 @@
|
|
|
677
677
|
}
|
|
678
678
|
]
|
|
679
679
|
},
|
|
680
|
+
{
|
|
681
|
+
"name": "cancelAllOrders",
|
|
682
|
+
"accounts": [
|
|
683
|
+
{
|
|
684
|
+
"name": "state",
|
|
685
|
+
"isMut": false,
|
|
686
|
+
"isSigner": false
|
|
687
|
+
},
|
|
688
|
+
{
|
|
689
|
+
"name": "orderState",
|
|
690
|
+
"isMut": false,
|
|
691
|
+
"isSigner": false
|
|
692
|
+
},
|
|
693
|
+
{
|
|
694
|
+
"name": "user",
|
|
695
|
+
"isMut": false,
|
|
696
|
+
"isSigner": false
|
|
697
|
+
},
|
|
698
|
+
{
|
|
699
|
+
"name": "authority",
|
|
700
|
+
"isMut": false,
|
|
701
|
+
"isSigner": true
|
|
702
|
+
},
|
|
703
|
+
{
|
|
704
|
+
"name": "markets",
|
|
705
|
+
"isMut": false,
|
|
706
|
+
"isSigner": false
|
|
707
|
+
},
|
|
708
|
+
{
|
|
709
|
+
"name": "userPositions",
|
|
710
|
+
"isMut": true,
|
|
711
|
+
"isSigner": false
|
|
712
|
+
},
|
|
713
|
+
{
|
|
714
|
+
"name": "userOrders",
|
|
715
|
+
"isMut": true,
|
|
716
|
+
"isSigner": false
|
|
717
|
+
},
|
|
718
|
+
{
|
|
719
|
+
"name": "fundingPaymentHistory",
|
|
720
|
+
"isMut": true,
|
|
721
|
+
"isSigner": false
|
|
722
|
+
},
|
|
723
|
+
{
|
|
724
|
+
"name": "orderHistory",
|
|
725
|
+
"isMut": true,
|
|
726
|
+
"isSigner": false
|
|
727
|
+
}
|
|
728
|
+
],
|
|
729
|
+
"args": []
|
|
730
|
+
},
|
|
680
731
|
{
|
|
681
732
|
"name": "expireOrders",
|
|
682
733
|
"accounts": [
|
package/src/index.ts
CHANGED
package/src/math/amm.ts
CHANGED
|
@@ -2,11 +2,8 @@ import { BN } from '@project-serum/anchor';
|
|
|
2
2
|
import {
|
|
3
3
|
AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO,
|
|
4
4
|
MARK_PRICE_PRECISION,
|
|
5
|
-
AMM_RESERVE_PRECISION,
|
|
6
5
|
PEG_PRECISION,
|
|
7
6
|
ZERO,
|
|
8
|
-
AMM_TO_QUOTE_PRECISION_RATIO,
|
|
9
|
-
QUOTE_PRECISION,
|
|
10
7
|
} from '../constants/numericConstants';
|
|
11
8
|
import {
|
|
12
9
|
AMM,
|
|
@@ -190,86 +187,3 @@ export function calculateMaxBaseAssetAmountToTrade(
|
|
|
190
187
|
return [new BN(0), PositionDirection.LONG];
|
|
191
188
|
}
|
|
192
189
|
}
|
|
193
|
-
|
|
194
|
-
export function calculateBudgetedK(market: Market, cost: BN): [BN, BN] {
|
|
195
|
-
// wolframalpha.com
|
|
196
|
-
// (1/(x+d) - p/(x*p+d))*y*d*Q = C solve for p
|
|
197
|
-
// p = (d(y*d*Q - C(x+d))) / (C*x(x+d) + y*y*d*Q)
|
|
198
|
-
|
|
199
|
-
// todo: assumes k = x * y
|
|
200
|
-
// otherwise use: (y(1-p) + (kp^2/(x*p+d)) - k/(x+d)) * Q = C solve for p
|
|
201
|
-
|
|
202
|
-
// const k = market.amm.sqrtK.mul(market.amm.sqrtK);
|
|
203
|
-
const x = market.amm.baseAssetReserve;
|
|
204
|
-
const y = market.amm.quoteAssetReserve;
|
|
205
|
-
|
|
206
|
-
const d = market.baseAssetAmount;
|
|
207
|
-
const Q = market.amm.pegMultiplier;
|
|
208
|
-
|
|
209
|
-
const C = cost.mul(new BN(-1));
|
|
210
|
-
|
|
211
|
-
const numer1 = y.mul(d).mul(Q).div(AMM_RESERVE_PRECISION).div(PEG_PRECISION);
|
|
212
|
-
const numer2 = C.mul(x.add(d)).div(QUOTE_PRECISION);
|
|
213
|
-
const denom1 = C.mul(x)
|
|
214
|
-
.mul(x.add(d))
|
|
215
|
-
.div(AMM_RESERVE_PRECISION)
|
|
216
|
-
.div(QUOTE_PRECISION);
|
|
217
|
-
const denom2 = y
|
|
218
|
-
.mul(d)
|
|
219
|
-
.mul(d)
|
|
220
|
-
.mul(Q)
|
|
221
|
-
.div(AMM_RESERVE_PRECISION)
|
|
222
|
-
.div(AMM_RESERVE_PRECISION)
|
|
223
|
-
.div(PEG_PRECISION);
|
|
224
|
-
|
|
225
|
-
const numerator = d
|
|
226
|
-
.mul(numer1.add(numer2))
|
|
227
|
-
.div(AMM_RESERVE_PRECISION)
|
|
228
|
-
.div(AMM_RESERVE_PRECISION)
|
|
229
|
-
.div(AMM_TO_QUOTE_PRECISION_RATIO);
|
|
230
|
-
const denominator = denom1
|
|
231
|
-
.add(denom2)
|
|
232
|
-
.div(AMM_RESERVE_PRECISION)
|
|
233
|
-
.div(AMM_TO_QUOTE_PRECISION_RATIO);
|
|
234
|
-
console.log(numerator, denominator);
|
|
235
|
-
// const p = (numerator).div(denominator);
|
|
236
|
-
|
|
237
|
-
// const formulaCost = (numer21.sub(numer20).sub(numer1)).mul(market.amm.pegMultiplier).div(AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO)
|
|
238
|
-
// console.log(convertToNumber(formulaCost, QUOTE_PRECISION))
|
|
239
|
-
|
|
240
|
-
return [numerator, denominator];
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
export function calculateBudgetedPeg(market: Market, cost: BN): BN {
|
|
244
|
-
// wolframalpha.com
|
|
245
|
-
// (1/(x+d) - p/(x*p+d))*y*d*Q = C solve for p
|
|
246
|
-
// p = (d(y*d*Q - C(x+d))) / (C*x(x+d) + y*y*d*Q)
|
|
247
|
-
|
|
248
|
-
// todo: assumes k = x * y
|
|
249
|
-
// otherwise use: (y(1-p) + (kp^2/(x*p+d)) - k/(x+d)) * Q = C solve for p
|
|
250
|
-
|
|
251
|
-
const k = market.amm.sqrtK.mul(market.amm.sqrtK);
|
|
252
|
-
const x = market.amm.baseAssetReserve;
|
|
253
|
-
const y = market.amm.quoteAssetReserve;
|
|
254
|
-
|
|
255
|
-
const d = market.baseAssetAmount;
|
|
256
|
-
const Q = market.amm.pegMultiplier;
|
|
257
|
-
|
|
258
|
-
const C = cost.mul(new BN(-1));
|
|
259
|
-
|
|
260
|
-
const deltaQuoteAssetReserves = y.sub(k.div(x.add(d)));
|
|
261
|
-
const deltaPegMultiplier = C.mul(MARK_PRICE_PRECISION)
|
|
262
|
-
.div(deltaQuoteAssetReserves.div(AMM_TO_QUOTE_PRECISION_RATIO))
|
|
263
|
-
.mul(PEG_PRECISION)
|
|
264
|
-
.div(QUOTE_PRECISION);
|
|
265
|
-
console.log(
|
|
266
|
-
Q.toNumber(),
|
|
267
|
-
'change by',
|
|
268
|
-
deltaPegMultiplier.toNumber() / MARK_PRICE_PRECISION.toNumber()
|
|
269
|
-
);
|
|
270
|
-
const newPeg = Q.sub(
|
|
271
|
-
deltaPegMultiplier.mul(PEG_PRECISION).div(MARK_PRICE_PRECISION)
|
|
272
|
-
);
|
|
273
|
-
|
|
274
|
-
return newPeg;
|
|
275
|
-
}
|
|
@@ -28,7 +28,7 @@ export class PythClient {
|
|
|
28
28
|
): Promise<OraclePriceData> {
|
|
29
29
|
const priceData = parsePriceData(buffer);
|
|
30
30
|
return {
|
|
31
|
-
price: convertPythPrice(priceData.price, priceData.exponent),
|
|
31
|
+
price: convertPythPrice(priceData.aggregate.price, priceData.exponent),
|
|
32
32
|
slot: new BN(priceData.lastSlot.toString()),
|
|
33
33
|
confidence: convertPythPrice(priceData.confidence, priceData.exponent),
|
|
34
34
|
twap: convertPythPrice(priceData.twap.value, priceData.exponent),
|
package/src/orderParams.ts
CHANGED
|
@@ -17,7 +17,8 @@ export function getLimitOrderParams(
|
|
|
17
17
|
referrer = false,
|
|
18
18
|
userOrderId = 0,
|
|
19
19
|
postOnly = false,
|
|
20
|
-
oraclePriceOffset = ZERO
|
|
20
|
+
oraclePriceOffset = ZERO,
|
|
21
|
+
immediateOrCancel = false
|
|
21
22
|
): OrderParams {
|
|
22
23
|
return {
|
|
23
24
|
orderType: OrderType.LIMIT,
|
|
@@ -29,7 +30,7 @@ export function getLimitOrderParams(
|
|
|
29
30
|
price,
|
|
30
31
|
reduceOnly,
|
|
31
32
|
postOnly,
|
|
32
|
-
immediateOrCancel
|
|
33
|
+
immediateOrCancel,
|
|
33
34
|
positionLimit: ZERO,
|
|
34
35
|
padding0: true,
|
|
35
36
|
padding1: ZERO,
|