@d8x/perpetuals-sdk 0.0.21 → 0.0.22

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.
@@ -1258,6 +1258,12 @@
1258
1258
  "name": "perpetualId",
1259
1259
  "type": "uint24"
1260
1260
  },
1261
+ {
1262
+ "indexed": false,
1263
+ "internalType": "int128",
1264
+ "name": "fMidPricePremium",
1265
+ "type": "int128"
1266
+ },
1261
1267
  {
1262
1268
  "indexed": false,
1263
1269
  "internalType": "int128",
@@ -2394,9 +2400,9 @@
2394
2400
  "name": "getAMMState",
2395
2401
  "outputs": [
2396
2402
  {
2397
- "internalType": "int128[13]",
2403
+ "internalType": "int128[15]",
2398
2404
  "name": "",
2399
- "type": "int128[13]"
2405
+ "type": "int128[15]"
2400
2406
  }
2401
2407
  ],
2402
2408
  "stateMutability": "view",
@@ -3694,6 +3700,30 @@
3694
3700
  "stateMutability": "view",
3695
3701
  "type": "function"
3696
3702
  },
3703
+ {
3704
+ "inputs": [
3705
+ {
3706
+ "internalType": "bytes4",
3707
+ "name": "_baseCurrency",
3708
+ "type": "bytes4"
3709
+ },
3710
+ {
3711
+ "internalType": "bytes4",
3712
+ "name": "_quoteCurrency",
3713
+ "type": "bytes4"
3714
+ }
3715
+ ],
3716
+ "name": "isMarketClosed",
3717
+ "outputs": [
3718
+ {
3719
+ "internalType": "bool",
3720
+ "name": "",
3721
+ "type": "bool"
3722
+ }
3723
+ ],
3724
+ "stateMutability": "view",
3725
+ "type": "function"
3726
+ },
3697
3727
  {
3698
3728
  "inputs": [
3699
3729
  {
@@ -3732,6 +3762,25 @@
3732
3762
  "stateMutability": "view",
3733
3763
  "type": "function"
3734
3764
  },
3765
+ {
3766
+ "inputs": [
3767
+ {
3768
+ "internalType": "uint24",
3769
+ "name": "_perpetualId",
3770
+ "type": "uint24"
3771
+ }
3772
+ ],
3773
+ "name": "isPerpMarketClosed",
3774
+ "outputs": [
3775
+ {
3776
+ "internalType": "bool",
3777
+ "name": "isClosed",
3778
+ "type": "bool"
3779
+ }
3780
+ ],
3781
+ "stateMutability": "view",
3782
+ "type": "function"
3783
+ },
3735
3784
  {
3736
3785
  "inputs": [
3737
3786
  {
@@ -65,12 +65,6 @@
65
65
  "name": "perpetualId",
66
66
  "type": "uint24"
67
67
  },
68
- {
69
- "indexed": false,
70
- "internalType": "uint16",
71
- "name": "brokerFeeTbps",
72
- "type": "uint16"
73
- },
74
68
  {
75
69
  "indexed": true,
76
70
  "internalType": "address",
@@ -90,46 +84,82 @@
90
84
  "type": "address"
91
85
  },
92
86
  {
87
+ "components": [
88
+ {
89
+ "internalType": "uint32",
90
+ "name": "flags",
91
+ "type": "uint32"
92
+ },
93
+ {
94
+ "internalType": "uint24",
95
+ "name": "iPerpetualId",
96
+ "type": "uint24"
97
+ },
98
+ {
99
+ "internalType": "uint16",
100
+ "name": "brokerFeeTbps",
101
+ "type": "uint16"
102
+ },
103
+ {
104
+ "internalType": "address",
105
+ "name": "traderAddr",
106
+ "type": "address"
107
+ },
108
+ {
109
+ "internalType": "address",
110
+ "name": "brokerAddr",
111
+ "type": "address"
112
+ },
113
+ {
114
+ "internalType": "address",
115
+ "name": "referrerAddr",
116
+ "type": "address"
117
+ },
118
+ {
119
+ "internalType": "bytes",
120
+ "name": "brokerSignature",
121
+ "type": "bytes"
122
+ },
123
+ {
124
+ "internalType": "int128",
125
+ "name": "fAmount",
126
+ "type": "int128"
127
+ },
128
+ {
129
+ "internalType": "int128",
130
+ "name": "fLimitPrice",
131
+ "type": "int128"
132
+ },
133
+ {
134
+ "internalType": "int128",
135
+ "name": "fTriggerPrice",
136
+ "type": "int128"
137
+ },
138
+ {
139
+ "internalType": "int128",
140
+ "name": "fLeverage",
141
+ "type": "int128"
142
+ },
143
+ {
144
+ "internalType": "uint64",
145
+ "name": "iDeadline",
146
+ "type": "uint64"
147
+ },
148
+ {
149
+ "internalType": "uint64",
150
+ "name": "createdTimestamp",
151
+ "type": "uint64"
152
+ },
153
+ {
154
+ "internalType": "uint64",
155
+ "name": "submittedBlock",
156
+ "type": "uint64"
157
+ }
158
+ ],
93
159
  "indexed": false,
94
- "internalType": "int128",
95
- "name": "tradeAmount",
96
- "type": "int128"
97
- },
98
- {
99
- "indexed": false,
100
- "internalType": "int128",
101
- "name": "limitPrice",
102
- "type": "int128"
103
- },
104
- {
105
- "indexed": false,
106
- "internalType": "int128",
107
- "name": "triggerPrice",
108
- "type": "int128"
109
- },
110
- {
111
- "indexed": false,
112
- "internalType": "uint64",
113
- "name": "deadline",
114
- "type": "uint64"
115
- },
116
- {
117
- "indexed": false,
118
- "internalType": "uint32",
119
- "name": "flags",
120
- "type": "uint32"
121
- },
122
- {
123
- "indexed": false,
124
- "internalType": "int128",
125
- "name": "leverage",
126
- "type": "int128"
127
- },
128
- {
129
- "indexed": false,
130
- "internalType": "uint64",
131
- "name": "createdTimestamp",
132
- "type": "uint64"
160
+ "internalType": "struct IPerpetualOrder.Order",
161
+ "name": "order",
162
+ "type": "tuple"
133
163
  },
134
164
  {
135
165
  "indexed": false,
@@ -1,9 +1,10 @@
1
1
  {
2
- "name": "v1.4",
3
- "proxyAddr": "0x7fe419fDE6c47F57B49Ef4D5D1ACD332307a734d",
2
+ "name": "v1.5",
3
+ "proxyAddr": "0xaB6AD25eE5CA28E7d7b16A33A33897aE34BF9e67",
4
4
  "nodeURL": "https://rpc-mumbai.maticvigil.com/",
5
5
  "proxyABILocation": "../abi/IPerpetualManager.json",
6
- "limitOrderBookFactoryAddr": "0x40aA68C1C33626ecD048a8A38aBF3947813cAF92",
6
+ "limitOrderBookFactoryAddr": "0xe95422bf27C62F3b9ae19d6032aC58c1bd13C71E",
7
7
  "limitOrderBookFactoryABILocation": "../abi/LimitOrderBookFactory.json",
8
- "limitOrderBookABILocation": "../abi/LimitOrderBook.json"
8
+ "limitOrderBookABILocation": "../abi/LimitOrderBook.json",
9
+ "symbolListLocation": "../config/symbolList.json"
9
10
  }
@@ -1,9 +1,10 @@
1
1
  {
2
- "name": "v1.3",
3
- "proxyAddr": "0x44Ae67695781209ace41c422dCfD29d3C678AF68",
2
+ "name": "v1.4",
3
+ "proxyAddr": "0x7fe419fDE6c47F57B49Ef4D5D1ACD332307a734d",
4
4
  "nodeURL": "https://rpc-mumbai.maticvigil.com/",
5
5
  "proxyABILocation": "../abi/IPerpetualManager.json",
6
- "limitOrderBookFactoryAddr": "0x5D9Af75B450be534d57106c817145f4E373069cb",
6
+ "limitOrderBookFactoryAddr": "0x40aA68C1C33626ecD048a8A38aBF3947813cAF92",
7
7
  "limitOrderBookFactoryABILocation": "../abi/LimitOrderBookFactory.json",
8
- "limitOrderBookABILocation": "../abi/LimitOrderBook.json"
8
+ "limitOrderBookABILocation": "../abi/LimitOrderBook.json",
9
+ "symbolListLocation": "../config/symbolList.json"
9
10
  }
@@ -0,0 +1,9 @@
1
+ [
2
+ { "symbol": "USD", "cleanSymbol": "USD" },
3
+ { "symbol": "BTC", "cleanSymbol": "BTC" },
4
+ { "symbol": "ETH", "cleanSymbol": "ETH" },
5
+ { "symbol": "MATIC", "cleanSymbol": "MATC" },
6
+ { "symbol": "CHF", "cleanSymbol": "CHF" },
7
+ { "symbol": "GBP", "cleanSymbol": "GBP" },
8
+ { "symbol": "XAU", "cleanSymbol": "XAU" }
9
+ ]
@@ -186,13 +186,13 @@ class AccountTrade extends writeAccessHandler_1.default {
186
186
  */
187
187
  queryExchangeFee(poolSymbolName, brokerAddr) {
188
188
  return __awaiter(this, void 0, void 0, function* () {
189
- if (this.proxyContract == null || this.signer == null) {
189
+ if (this.proxyContract == null) {
190
190
  throw Error("no proxy contract or wallet initialized. Use createProxyInstance().");
191
191
  }
192
192
  if (typeof brokerAddr == "undefined") {
193
193
  brokerAddr = nodeSDKTypes_1.ZERO_ADDRESS;
194
194
  }
195
- let poolId = writeAccessHandler_1.default._getPoolIdFromSymbol(poolSymbolName, this.poolStaticInfos);
195
+ let poolId = perpetualDataHandler_1.default._getPoolIdFromSymbol(poolSymbolName, this.poolStaticInfos);
196
196
  let feeTbps = yield this.proxyContract.queryExchangeFee(poolId, this.traderAddr, brokerAddr);
197
197
  return feeTbps / 100000;
198
198
  });
package/dist/d8XMath.d.ts CHANGED
@@ -72,3 +72,19 @@ export declare function calculateLiquidationPriceCollateralQuanto(LockedInValueQ
72
72
  * @returns {number} Amount to be deposited to have the given leverage when trading into position pos
73
73
  */
74
74
  export declare function calculateLiquidationPriceCollateralQuote(LockedInValueQC: number, position: number, cash_cc: number, maintenance_margin_rate: number): number;
75
+ /**
76
+ *
77
+ * @param targetLeverage Leverage of the resulting position. It must be positive unless the resulting position is closed.
78
+ * @param currentPosition Current position size, in base currency, signed.
79
+ * @param currentLockedInValue Current locked in value, average entry price times position size, in quote currency.
80
+ * @param tradeAmount Trade amount, in base currency, signed.
81
+ * @param markPrice Mark price, positive.
82
+ * @param indexPriceS2 Index price, positive.
83
+ * @param indexPriceS3 Collateral index price, positive.
84
+ * @param tradePrice Expected price to trade tradeAmount.
85
+ * @param feeRate
86
+ * @returns
87
+ */
88
+ export declare function getMarginRequiredForLeveragedTrade(targetLeverage: number | undefined, currentPosition: number, currentLockedInValue: number, tradeAmount: number, markPrice: number, indexPriceS2: number, indexPriceS3: number, tradePrice: number, feeRate: number): number;
89
+ export declare function getMaxSignedPositionSize(marginCollateral: number, currentPosition: number, currentLockedInValue: number, direction: number, limitPrice: number, initialMarginRate: number, feeRate: number, markPrice: number, indexPriceS2: number, indexPriceS3: number): number;
90
+ export declare function getNewPositionLeverage(tradeAmount: number, marginCollateral: number, currentPosition: number, currentLockedInValue: number, indexPriceS2: number, indexPriceS3: number, markPrice: number, limitPrice: number, feeRate: number): number;
package/dist/d8XMath.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.calculateLiquidationPriceCollateralQuote = exports.calculateLiquidationPriceCollateralQuanto = exports.calculateLiquidationPriceCollateralBase = exports.div64x64 = exports.mul64x64 = exports.floatToDec18 = exports.floatToABK64x64 = exports.dec18ToFloat = exports.ABK64x64ToFloat = void 0;
3
+ exports.getNewPositionLeverage = exports.getMaxSignedPositionSize = exports.getMarginRequiredForLeveragedTrade = exports.calculateLiquidationPriceCollateralQuote = exports.calculateLiquidationPriceCollateralQuanto = exports.calculateLiquidationPriceCollateralBase = exports.div64x64 = exports.mul64x64 = exports.floatToDec18 = exports.floatToABK64x64 = exports.dec18ToFloat = exports.ABK64x64ToFloat = void 0;
4
4
  const ethers_1 = require("ethers");
5
5
  const nodeSDKTypes_1 = require("./nodeSDKTypes");
6
6
  /**
@@ -162,3 +162,50 @@ function calculateLiquidationPriceCollateralQuote(LockedInValueQC, position, cas
162
162
  return numerator / denominator;
163
163
  }
164
164
  exports.calculateLiquidationPriceCollateralQuote = calculateLiquidationPriceCollateralQuote;
165
+ /**
166
+ *
167
+ * @param targetLeverage Leverage of the resulting position. It must be positive unless the resulting position is closed.
168
+ * @param currentPosition Current position size, in base currency, signed.
169
+ * @param currentLockedInValue Current locked in value, average entry price times position size, in quote currency.
170
+ * @param tradeAmount Trade amount, in base currency, signed.
171
+ * @param markPrice Mark price, positive.
172
+ * @param indexPriceS2 Index price, positive.
173
+ * @param indexPriceS3 Collateral index price, positive.
174
+ * @param tradePrice Expected price to trade tradeAmount.
175
+ * @param feeRate
176
+ * @returns
177
+ */
178
+ function getMarginRequiredForLeveragedTrade(targetLeverage, currentPosition, currentLockedInValue, tradeAmount, markPrice, indexPriceS2, indexPriceS3, tradePrice, feeRate) {
179
+ // we solve for margin in:
180
+ // |new position| * Sm / leverage + fee rate * |trade amount| * S2 = margin * S3 + current position * Sm - L + trade amount * (Sm - trade price)
181
+ // --> M S3 = |P'|Sm/L + FeeQC - PnL + (P'-P)(Price - Sm) = pos value / leverage + fees + price impact - pnl
182
+ let isClosing = currentPosition != 0 && currentPosition * tradeAmount < 0 && currentPosition * (currentPosition + tradeAmount) >= 0;
183
+ let feesCC = (feeRate * Math.abs(tradeAmount) * indexPriceS2) / indexPriceS3;
184
+ let collRequired = feesCC;
185
+ if (!isClosing) {
186
+ if (targetLeverage == undefined || targetLeverage <= 0) {
187
+ throw Error("opening trades must have positive leverage");
188
+ }
189
+ // unrealized pnl (could be + or -) - price impact premium (+)
190
+ let pnlQC = currentPosition * markPrice - currentLockedInValue - tradeAmount * (tradePrice - markPrice);
191
+ collRequired +=
192
+ Math.max(0, (Math.abs(currentPosition + tradeAmount) * markPrice) / targetLeverage - pnlQC) / indexPriceS3;
193
+ }
194
+ return collRequired;
195
+ }
196
+ exports.getMarginRequiredForLeveragedTrade = getMarginRequiredForLeveragedTrade;
197
+ function getMaxSignedPositionSize(marginCollateral, currentPosition, currentLockedInValue, direction, limitPrice, initialMarginRate, feeRate, markPrice, indexPriceS2, indexPriceS3) {
198
+ // we solve for new position in:
199
+ // |new position| * Sm / leverage + fee rate * |trade amount| * S2 = margin * S3 + current position * Sm - L + trade amount * (Sm - entry price)
200
+ // |trade amount| = (new position - current position) * direction
201
+ let availableCash = marginCollateral * indexPriceS3 + currentPosition * markPrice - currentLockedInValue;
202
+ let effectiveMarginRate = markPrice * initialMarginRate + feeRate * indexPriceS2 + direction * (limitPrice - markPrice);
203
+ return availableCash / effectiveMarginRate;
204
+ }
205
+ exports.getMaxSignedPositionSize = getMaxSignedPositionSize;
206
+ function getNewPositionLeverage(tradeAmount, marginCollateral, currentPosition, currentLockedInValue, indexPriceS2, indexPriceS3, markPrice, limitPrice, feeRate) {
207
+ let newPosition = tradeAmount + currentPosition;
208
+ let pnlQC = currentPosition * markPrice - currentLockedInValue + tradeAmount * (markPrice - limitPrice);
209
+ return ((Math.abs(newPosition) * indexPriceS2) / (marginCollateral * indexPriceS3 + pnlQC - feeRate * Math.abs(tradeAmount)));
210
+ }
211
+ exports.getNewPositionLeverage = getNewPositionLeverage;
@@ -0,0 +1,14 @@
1
+ import WriteAccessHandler from "./writeAccessHandler";
2
+ import { NodeSDKConfig } from "./nodeSDKTypes";
3
+ /**
4
+ * LiquidatorTool
5
+ * Methods to liquidate traders
6
+ */
7
+ export default class LiquidatorTool extends WriteAccessHandler {
8
+ /**
9
+ * Constructor
10
+ * @param config configuration
11
+ * @param privateKey private key of account that trades
12
+ */
13
+ constructor(config: NodeSDKConfig, privateKey: string);
14
+ }
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const writeAccessHandler_1 = __importDefault(require("./writeAccessHandler"));
7
+ /**
8
+ * LiquidatorTool
9
+ * Methods to liquidate traders
10
+ */
11
+ class LiquidatorTool extends writeAccessHandler_1.default {
12
+ /**
13
+ * Constructor
14
+ * @param config configuration
15
+ * @param privateKey private key of account that trades
16
+ */
17
+ constructor(config, privateKey) {
18
+ super(config, privateKey);
19
+ }
20
+ }
21
+ exports.default = LiquidatorTool;
@@ -1,7 +1,7 @@
1
- import { ExchangeInfo, NodeSDKConfig, MarginAccount } from "./nodeSDKTypes";
1
+ import { ExchangeInfo, NodeSDKConfig, MarginAccount, PerpetualState, PoolStaticInfo } from "./nodeSDKTypes";
2
2
  import { ethers } from "ethers";
3
3
  import PerpetualDataHandler from "./perpetualDataHandler";
4
- import { Order } from "./nodeSDKTypes";
4
+ import { SmartContractOrder, Order } from "./nodeSDKTypes";
5
5
  import "./nodeSDKTypes";
6
6
  /**
7
7
  * Functions to access market data (e.g., information on open orders, information on products that can be traded).
@@ -36,6 +36,12 @@ export default class MarketData extends PerpetualDataHandler {
36
36
  * @param provider optional provider
37
37
  */
38
38
  createProxyInstance(provider?: ethers.providers.JsonRpcProvider): Promise<void>;
39
+ /**
40
+ * Convert the smart contract output of an order into a convenient format of type "Order"
41
+ * @param smOrder SmartContractOrder, as obtained e.g., by PerpetualLimitOrderCreated event
42
+ * @returns more convenient format of order, type "Order"
43
+ */
44
+ smartContractOrderToOrder(smOrder: SmartContractOrder): Order;
39
45
  /**
40
46
  * Get contract instance. Useful for event listening.
41
47
  * @example
@@ -100,9 +106,9 @@ export default class MarketData extends PerpetualDataHandler {
100
106
  orderIds: string[];
101
107
  }>;
102
108
  /**
103
- * Information about the positions open by a given trader in a given perpetual contract.
109
+ * Information about the position open by a given trader in a given perpetual contract.
104
110
  * @param {string} traderAddr Address of the trader for which we get the position risk.
105
- * @param {string} symbol Symbol of the form ETH-USD-MATIC.
111
+ * @param {string} symbol Symbol of the form ETH-USD-MATIC. Can also be the perpetual id as string
106
112
  * @example
107
113
  * import { MarketData, PerpetualDataHandler } from '@d8x/perpetuals-sdk';
108
114
  * async function main() {
@@ -121,6 +127,8 @@ export default class MarketData extends PerpetualDataHandler {
121
127
  * @returns {MarginAccount}
122
128
  */
123
129
  positionRisk(traderAddr: string, symbol: string): Promise<MarginAccount>;
130
+ positionRiskOnTrade(traderAddr: string, order: Order, perpetualState: PerpetualState, currentPositionRisk?: MarginAccount): Promise<MarginAccount>;
131
+ maxOrderSizeForTrader(side: string, positionRisk: MarginAccount, perpetualState: PerpetualState): number;
124
132
  /**
125
133
  * Uses the Oracle(s) in the exchange to get the latest price of a given index in a given currency, if a route exists.
126
134
  * @param {string} base Index name, e.g. ETH.
@@ -183,6 +191,32 @@ export default class MarketData extends PerpetualDataHandler {
183
191
  * @returns price (number)
184
192
  */
185
193
  getPerpetualPrice(symbol: string, quantity: number): Promise<number>;
194
+ /**
195
+ * Query recent perpetual state from blockchain
196
+ * @param symbol symbol of the form ETH-USD-MATIC
197
+ * @returns PerpetualState reference
198
+ */
199
+ getPerpetualState(symbol: string): Promise<PerpetualState>;
200
+ /**
201
+ * get the current mid-price for a perpetual
202
+ * @param symbol symbol of the form ETH-USD-MATIC
203
+ * @example
204
+ * import { MarketData, PerpetualDataHandler } from '@d8x/perpetuals-sdk';
205
+ * async function main() {
206
+ * console.log(MarketData);
207
+ * // setup
208
+ * const config = PerpetualDataHandler.readSDKConfig("testnet");
209
+ * let mktData = new MarketData(config);
210
+ * await mktData.createProxyInstance();
211
+ * // get perpetual mid price
212
+ * let midPrice = await mktData.getPerpetualMidPrice("ETH-USD-MATIC");
213
+ * console.log(midPrice);
214
+ * }
215
+ * main();
216
+ *
217
+ * @returns {number} price
218
+ */
219
+ getPerpetualMidPrice(symbol: string): Promise<number>;
186
220
  /**
187
221
  * Query smart contract to get user orders and convert to user friendly order format.
188
222
  * @param {string} traderAddr Address of trader.
@@ -199,5 +233,7 @@ export default class MarketData extends PerpetualDataHandler {
199
233
  * @ignore
200
234
  */
201
235
  static orderIdsOfTrader(traderAddr: string, orderBookContract: ethers.Contract): Promise<string[]>;
202
- static _exchangeInfo(_proxyContract: ethers.Contract): Promise<ExchangeInfo>;
236
+ static _exchangeInfo(_proxyContract: ethers.Contract, _poolStaticInfos: Array<PoolStaticInfo>, _symbolList: Array<{
237
+ [key: string]: string;
238
+ }>): Promise<ExchangeInfo>;
203
239
  }