@d8x/perpetuals-sdk 0.0.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.
Files changed (46) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +17 -0
  3. package/abi/ERC20.json +288 -0
  4. package/abi/IPerpetualManager.json +4674 -0
  5. package/abi/LimitOrderBook.json +865 -0
  6. package/abi/LimitOrderBookFactory.json +166 -0
  7. package/config/defaultConfig.json +9 -0
  8. package/config/oldConfig.json +9 -0
  9. package/dist/accountTrade.d.ts +54 -0
  10. package/dist/accountTrade.js +164 -0
  11. package/dist/brokerTool.d.ts +41 -0
  12. package/dist/brokerTool.js +129 -0
  13. package/dist/d8XMath.d.ts +71 -0
  14. package/dist/d8XMath.js +162 -0
  15. package/dist/index.d.ts +11 -0
  16. package/dist/index.js +49 -0
  17. package/dist/liquiditatorTool.d.ts +14 -0
  18. package/dist/liquiditatorTool.js +21 -0
  19. package/dist/liquidityProviderTool.d.ts +39 -0
  20. package/dist/liquidityProviderTool.js +100 -0
  21. package/dist/marketData.d.ts +39 -0
  22. package/dist/marketData.js +160 -0
  23. package/dist/nodeSDKTypes.d.ts +130 -0
  24. package/dist/nodeSDKTypes.js +52 -0
  25. package/dist/orderReferrerTool.d.ts +14 -0
  26. package/dist/orderReferrerTool.js +21 -0
  27. package/dist/perpetualDataHandler.d.ts +85 -0
  28. package/dist/perpetualDataHandler.js +474 -0
  29. package/dist/utils.d.ts +37 -0
  30. package/dist/utils.js +84 -0
  31. package/dist/writeAccessHandler.d.ts +36 -0
  32. package/dist/writeAccessHandler.js +95 -0
  33. package/module.d.ts +1 -0
  34. package/package.json +63 -0
  35. package/src/accountTrade.ts +217 -0
  36. package/src/brokerTool.ts +155 -0
  37. package/src/d8XMath.ts +176 -0
  38. package/src/index.ts +32 -0
  39. package/src/liquiditatorTool.ts +21 -0
  40. package/src/liquidityProviderTool.ts +100 -0
  41. package/src/marketData.ts +149 -0
  42. package/src/nodeSDKTypes.ts +158 -0
  43. package/src/orderReferrerTool.ts +17 -0
  44. package/src/perpetualDataHandler.ts +549 -0
  45. package/src/utils.ts +83 -0
  46. package/src/writeAccessHandler.ts +83 -0
package/src/d8XMath.ts ADDED
@@ -0,0 +1,176 @@
1
+ import { BigNumber } from "ethers";
2
+ import { DECIMALS, ONE_64x64 } from "./nodeSDKTypes";
3
+ const BN = BigNumber;
4
+
5
+ /**
6
+ * Convert ABK64x64 bigint-format to float.
7
+ * Result = x/2^64 if big number, x/2^29 if number
8
+ * @param x number in ABDK-format or 2^29
9
+ * @returns x/2^64 in number-format (float)
10
+ */
11
+ export function ABK64x64ToFloat(x: BigNumber | number): number {
12
+ if (typeof x == "number") {
13
+ return x / 2 ** 29;
14
+ }
15
+ let s = x.lt(0) ? -1 : 1;
16
+ x = x.mul(s);
17
+ let xInt = x.div(ONE_64x64);
18
+ let dec18 = BigNumber.from(10).pow(BigNumber.from(18));
19
+ let xDec = x.sub(xInt.mul(ONE_64x64));
20
+ xDec = xDec.mul(dec18).div(ONE_64x64);
21
+ let k = 18 - xDec.toString().length;
22
+ // console.assert(k >= 0);
23
+ let sPad = "0".repeat(k);
24
+ let NumberStr = xInt.toString() + "." + sPad + xDec.toString();
25
+ return parseFloat(NumberStr) * s;
26
+ }
27
+
28
+ /**
29
+ *
30
+ * @param x BigNumber in Dec18 format
31
+ * @returns x as a float (number)
32
+ */
33
+ export function dec18ToFloat(x: BigNumber): number {
34
+ //x: BigNumber in Dec18 format to float
35
+ let s = x.lt(0) ? -1 : 1;
36
+ x = x.mul(s);
37
+ let xInt = x.div(DECIMALS);
38
+ let xDec = x.sub(xInt.mul(DECIMALS));
39
+ let k = 18 - xDec.toString().length;
40
+ let sPad = "0".repeat(k);
41
+ let NumberStr = xInt.toString() + "." + sPad + xDec.toString();
42
+ return parseFloat(NumberStr) * s;
43
+ }
44
+
45
+ /**
46
+ * Converts x into ABDK64x64 format
47
+ * @param x number (float)
48
+ * @returns x^64 in big number format
49
+ */
50
+ export function floatToABK64x64(x: number): BigNumber {
51
+ // convert float to ABK64x64 bigint-format
52
+ // Create string from number with 18 decimals
53
+ if (x === 0) {
54
+ return BigNumber.from(0);
55
+ }
56
+ let sg = Math.sign(x);
57
+ x = Math.abs(x);
58
+ let strX = Number(x).toFixed(18);
59
+ const arrX = strX.split(".");
60
+ let xInt = BigNumber.from(arrX[0]);
61
+ let xDec = BigNumber.from(arrX[1]);
62
+ let xIntBig = xInt.mul(ONE_64x64);
63
+ let dec18 = BigNumber.from(10).pow(BigNumber.from(18));
64
+ let xDecBig = xDec.mul(ONE_64x64).div(dec18);
65
+ return xIntBig.add(xDecBig).mul(sg);
66
+ }
67
+
68
+ /**
69
+ *
70
+ * @param x number (float)
71
+ * @returns x as a BigNumber in Dec18 format
72
+ */
73
+ export function floatToDec18(x: number): BigNumber {
74
+ // float number to dec 18
75
+ if (x === 0) {
76
+ return BigNumber.from(0);
77
+ }
78
+ let sg = Math.sign(x);
79
+ x = Math.abs(x);
80
+ let strX = x.toFixed(18);
81
+ const arrX = strX.split(".");
82
+ let xInt = BigNumber.from(arrX[0]);
83
+ let xDec = BigNumber.from(arrX[1]);
84
+ let xIntBig = xInt.mul(DECIMALS);
85
+ return xIntBig.add(xDec).mul(sg);
86
+ }
87
+
88
+ /**
89
+ *
90
+ * @param x
91
+ * @param y
92
+ * @returns x * y
93
+ */
94
+ export function mul64x64(x: BigNumber, y: BigNumber) {
95
+ return x.mul(y).div(ONE_64x64);
96
+ }
97
+
98
+ /**
99
+ *
100
+ * @param x
101
+ * @param y
102
+ * @returns x / y
103
+ */
104
+ export function div64x64(x: BigNumber, y: BigNumber) {
105
+ return x.mul(ONE_64x64).div(y);
106
+ }
107
+
108
+ /**
109
+ * Determine the liquidation price
110
+ * @param {number} LockedInValueQC - trader locked in value in quote currency
111
+ * @param {number} position - trader position in base currency
112
+ * @param {number} cash_cc - trader available margin cash in collateral currency
113
+ * @param {number} maintenance_margin_rate - maintenance margin ratio
114
+ * @param {number} S3 - collateral to quote conversion (=S2 if base-collateral, =1 if quuote collateral, = index S3 if quanto)
115
+ * @returns {number} Amount to be deposited to have the given leverage when trading into position pos
116
+ */
117
+ export function calculateLiquidationPriceCollateralBase(
118
+ LockedInValueQC: number,
119
+ position: number,
120
+ cash_cc: number,
121
+ maintenance_margin_rate: number
122
+ ): number {
123
+ // correct only if markprice = spot price
124
+ // m_r <= (Sm * Pi - L + cash * S3) / (Sm * |Pi|)
125
+ // -> Sm * (Pi + cash - m_r|Pi|) => L
126
+ return LockedInValueQC / (position - maintenance_margin_rate * Math.abs(position) + cash_cc);
127
+ }
128
+
129
+ /**
130
+ * Determine the liquidation price
131
+ * @param {number} LockedInValueQC - trader locked in value in quote currency
132
+ * @param {number} position - trader position in base currency
133
+ * @param {number} cash_cc - trader available margin cash in collateral currency
134
+ * @param {number} maintenance_margin_rate - maintenance margin ratio
135
+ * @param {number} S3 - collateral to quote conversion (=S2 if base-collateral, =1 if quuote collateral, = index S3 if quanto)
136
+ * @param {number} Sm - mark price
137
+ * @returns {number} Amount to be deposited to have the given leverage when trading into position pos
138
+ */
139
+ export function calculateLiquidationPriceCollateralQuanto(
140
+ LockedInValueQC: number,
141
+ position: number,
142
+ cash_cc: number,
143
+ maintenance_margin_rate: number,
144
+ S3: number,
145
+ Sm: number
146
+ ): number {
147
+ // correct only if markprice = spot price and S3 co-moves with Sm
148
+ // m_r = (Sm * Pi - L + cash * S3) / (Sm * |Pi|)
149
+ // m_r = [Sm * Pi - L + cash * S3(0) * (1 + sign(Pi) (Sm / Sm(0) - 1)] / (Sm * |Pi|)
150
+ // -> Sm * (m_r |Pi| - Pi - cash * S3(0) * sign(Pi) / Sm(0)) = - L + cash * S3(0) * (1 - sign(Pi))
151
+ let numerator = -LockedInValueQC + cash_cc * S3 * (1 - Math.sign(position));
152
+ let denominator = maintenance_margin_rate * Math.abs(position) - position - (cash_cc * S3 * Math.sign(position)) / Sm;
153
+ return numerator / denominator;
154
+ }
155
+
156
+ /**
157
+ * Determine the liquidation price
158
+ * @param {number} LockedInValueQC - trader locked in value in quote currency
159
+ * @param {number} position - trader position in base currency
160
+ * @param {number} cash_cc - trader available margin cash in collateral currency
161
+ * @param {number} maintenance_margin_rate - maintenance margin ratio
162
+ * @param {number} S3 - collateral to quote conversion (=S2 if base-collateral, =1 if quuote collateral, = index S3 if quanto)
163
+ * @returns {number} Amount to be deposited to have the given leverage when trading into position pos
164
+ */
165
+ export function calculateLiquidationPriceCollateralQuote(
166
+ LockedInValueQC: number,
167
+ position: number,
168
+ cash_cc: number,
169
+ maintenance_margin_rate: number
170
+ ): number {
171
+ // m_r = (Sm * Pi - L + cash ) / (Sm * |Pi|)
172
+ // -> Sm * (m_r |Pi| - Pi) = - L + cash
173
+ let numerator = -LockedInValueQC + cash_cc;
174
+ let denominator = maintenance_margin_rate * Math.abs(position) - position;
175
+ return numerator / denominator;
176
+ }
package/src/index.ts ADDED
@@ -0,0 +1,32 @@
1
+ import AccountTrade from "./accountTrade";
2
+ import BrokerTool from "./brokerTool";
3
+ import LiquidityProviderTool from "./liquidityProviderTool";
4
+ import MarketData from "./marketData";
5
+ import OrderReferrerTool from "./orderReferrerTool";
6
+ import PerpetualDataHandler from "./perpetualDataHandler";
7
+ import WriteAccessHandler from "./writeAccessHandler";
8
+ // import {
9
+ // NodeSDKConfig,
10
+ // MarginAccount,
11
+ // CollaterlCCY,
12
+ // PoolStaticInfo,
13
+ // PerpetualStaticInfo,
14
+ // ExchangeInfo,
15
+ // PoolState,
16
+ // PerpetualState,
17
+ // Order,
18
+ // SmartContractOrder,
19
+ // } from "./nodeSDKTypes";
20
+ export * from "./nodeSDKTypes";
21
+ export * from "./utils";
22
+ export * from "./d8XMath";
23
+
24
+ export {
25
+ AccountTrade,
26
+ BrokerTool,
27
+ LiquidityProviderTool,
28
+ MarketData,
29
+ OrderReferrerTool,
30
+ PerpetualDataHandler,
31
+ WriteAccessHandler,
32
+ };
@@ -0,0 +1,21 @@
1
+ import WriteAccessHandler from "./writeAccessHandler";
2
+ import { NodeSDKConfig } from "./nodeSDKTypes";
3
+
4
+ /**
5
+ * LiquidatorTool
6
+ * Methods to liquidate traders
7
+ */
8
+ export default class LiquidatorTool extends WriteAccessHandler {
9
+ /**
10
+ * Constructor
11
+ * @param config configuration
12
+ * @param privateKey private key of account that trades
13
+ */
14
+ public constructor(config: NodeSDKConfig, privateKey: string) {
15
+ super(config, privateKey);
16
+ }
17
+
18
+ /*
19
+ TODO
20
+ */
21
+ }
@@ -0,0 +1,100 @@
1
+ import { ethers } from "ethers";
2
+ import WriteAccessHandler from "./writeAccessHandler";
3
+ import { NodeSDKConfig, ERC20_ABI } from "./nodeSDKTypes";
4
+ import PerpetualDataHandler from "./perpetualDataHandler";
5
+ import { floatToABK64x64, dec18ToFloat, ABK64x64ToFloat } from "./d8XMath";
6
+ /**
7
+ * LiquidityProviderTool
8
+ * Methods to provide liquidity
9
+ */
10
+ export default class LiquidityProviderTool extends WriteAccessHandler {
11
+ /**
12
+ * Constructor
13
+ * @param config configuration
14
+ * @param privateKey private key of account that trades
15
+ */
16
+ public constructor(config: NodeSDKConfig, privateKey: string) {
17
+ super(config, privateKey);
18
+ }
19
+
20
+ /**
21
+ * Returns the value of the share tokens for this liquidity provider
22
+ * in poolSymbol-currency (e.g. MATIC, USDC)
23
+ * @param poolSymbolName pool symbol name (e.g. MATIC)
24
+ */
25
+ public async getParticipationValue(
26
+ poolSymbolName: string
27
+ ): Promise<{ value: number; shareTokenBalance: number; poolShareToken: string }> {
28
+ if (
29
+ this.proxyContract == null ||
30
+ this.signer == null ||
31
+ this.poolStaticInfos.length == 0 ||
32
+ this.provider == null
33
+ ) {
34
+ throw Error("no proxy contract or wallet or data initialized. Use createProxyInstance().");
35
+ }
36
+ let poolId = PerpetualDataHandler._getPoolIdFromSymbol(poolSymbolName, this.poolStaticInfos);
37
+
38
+ let shareTokenAddr = this.poolStaticInfos[poolId - 1].shareTokenAddr;
39
+ let shareToken = new ethers.Contract(shareTokenAddr, ERC20_ABI, this.signer);
40
+ let dShareTokenBalanceOfAddr = await shareToken.balanceOf(this.traderAddr);
41
+ let shareTokenBalanceOfAddr = dec18ToFloat(dShareTokenBalanceOfAddr);
42
+ if (shareTokenBalanceOfAddr == 0) {
43
+ return { value: 0, shareTokenBalance: 0, poolShareToken: shareTokenAddr };
44
+ }
45
+ let pool = await this.proxyContract.getLiquidityPool(poolId);
46
+ let fPnLParticipantFundCash = pool.fPnLparticipantsCashCC;
47
+ let pnlParticipantFundCash = ABK64x64ToFloat(fPnLParticipantFundCash);
48
+
49
+ let dTotalSupply = await shareToken.totalSupply();
50
+
51
+ let totalSupply = dec18ToFloat(dTotalSupply);
52
+ let valueCC = (shareTokenBalanceOfAddr / totalSupply) * pnlParticipantFundCash;
53
+ return { value: valueCC, shareTokenBalance: shareTokenBalanceOfAddr, poolShareToken: shareTokenAddr };
54
+ }
55
+
56
+ /**
57
+ * Add liquidity to the PnL participant fund. The address gets pool shares in return.
58
+ * @param poolname name of pool symbol (e.g. MATIC)
59
+ * @param amountCC amount in pool-collateral currency
60
+ * @return transaction object
61
+ */
62
+ public async addLiquidity(poolSymbolName: string, amountCC: number): Promise<ethers.providers.TransactionResponse> {
63
+ if (this.proxyContract == null || this.signer == null) {
64
+ throw Error("no proxy contract or wallet initialized. Use createProxyInstance().");
65
+ }
66
+ let poolId = PerpetualDataHandler._getPoolIdFromSymbol(poolSymbolName, this.poolStaticInfos);
67
+ let tx = await this.proxyContract.addLiquidity(poolId, floatToABK64x64(amountCC), {
68
+ gasLimit: this.gasLimit,
69
+ });
70
+ return tx;
71
+ }
72
+
73
+ /**
74
+ * Remove liquidity from the pool
75
+ * @param poolSymbolName name of pool symbol (e.g. MATIC)
76
+ * @param amountPoolShares amount in pool-tokens, removes everything if > available amount
77
+ * @return transaction object
78
+ */
79
+ public async removeLiquidity(
80
+ poolSymbolName: string,
81
+ amountPoolShares: number
82
+ ): Promise<ethers.providers.TransactionResponse> {
83
+ if (this.proxyContract == null || this.signer == null) {
84
+ throw Error("no proxy contract or wallet initialized. Use createProxyInstance().");
85
+ }
86
+ let poolId = PerpetualDataHandler._getPoolIdFromSymbol(poolSymbolName, this.poolStaticInfos);
87
+ let tx = await this.proxyContract.addLiquidity(poolId, floatToABK64x64(amountPoolShares), {
88
+ gasLimit: this.gasLimit,
89
+ });
90
+ return tx;
91
+ }
92
+
93
+ /*
94
+ TODO:
95
+ - add liquidity
96
+ addLiquidity(uint8 _poolId, int128 _fTokenAmount)
97
+ - remove liquidity
98
+ function removeLiquidity(uint8 _poolId, int128 _fShareAmount) external override nonReentrant
99
+ */
100
+ }
@@ -0,0 +1,149 @@
1
+ import {
2
+ ExchangeInfo,
3
+ NodeSDKConfig,
4
+ MarginAccount,
5
+ PoolState,
6
+ PerpetualState,
7
+ COLLATERAL_CURRENCY_BASE,
8
+ COLLATERAL_CURRENCY_QUANTO,
9
+ PERP_STATE_STR,
10
+ ZERO_ADDRESS,
11
+ } from "./nodeSDKTypes";
12
+ import { BigNumber, BytesLike, ethers } from "ethers";
13
+ import { floatToABK64x64, ABK64x64ToFloat } from "./d8XMath";
14
+ import { fromBytes4HexString } from "./utils";
15
+ import PerpetualDataHandler from "./perpetualDataHandler";
16
+ import { SmartContractOrder, Order } from "./nodeSDKTypes";
17
+
18
+ /**
19
+ * This class requires no private key and is blockchain read-only.
20
+ * No gas required for the queries here.
21
+ */
22
+ export default class MarketData extends PerpetualDataHandler {
23
+ public constructor(config: NodeSDKConfig) {
24
+ super(config);
25
+ }
26
+
27
+ public async createProxyInstance() {
28
+ this.provider = new ethers.providers.JsonRpcProvider(this.nodeURL);
29
+ await this.initContractsAndData(this.provider);
30
+ }
31
+
32
+ public async exchangeInfo(): Promise<ExchangeInfo> {
33
+ if (this.proxyContract == null) {
34
+ throw Error("no proxy contract initialized. Use createProxyInstance().");
35
+ }
36
+ return await MarketData._exchangeInfo(this.proxyContract);
37
+ }
38
+
39
+ /**
40
+ * Get all open orders for a trader-address and a symbol
41
+ * @param traderAddr address of the trader for which we get the open order
42
+ * @param symbol symbol of the form ETH-USD-MATIC
43
+ * @returns array of open orders and corresponding order-ids
44
+ */
45
+ public async openOrders(traderAddr: string, symbol: string): Promise<{ orders: Order[]; orderIds: string[] }> {
46
+ // open orders requested only for given symbol
47
+ let orderBookContract = this.getOrderBookContract(symbol);
48
+ let [orders, digests] = await Promise.all([
49
+ this.openOrdersOnOrderBook(traderAddr, orderBookContract),
50
+ this.orderIdsOfTrader(traderAddr, orderBookContract),
51
+ ]);
52
+ return { orders: orders, orderIds: digests };
53
+ }
54
+
55
+ public async positionRisk(traderAddr: string, symbol: string): Promise<MarginAccount> {
56
+ if (this.proxyContract == null) {
57
+ throw Error("no proxy contract initialized. Use createProxyInstance().");
58
+ }
59
+ let mgnAcct = await PerpetualDataHandler.getMarginAccount(traderAddr, symbol, this.symbolToPerpStaticInfo, this.proxyContract);
60
+ return mgnAcct;
61
+ }
62
+
63
+ /**
64
+ * Query smart contract to get user orders and convert to user friendly order format
65
+ * @param traderAddr address of trader
66
+ * @param orderBookContract instance of order book
67
+ * @returns array of user friendly order struct
68
+ */
69
+ protected async openOrdersOnOrderBook(traderAddr: string, orderBookContract: ethers.Contract): Promise<Order[]> {
70
+ let orders: SmartContractOrder[] = await orderBookContract.getOrders(traderAddr, 0, 15);
71
+ //eliminate empty orders and map to user friendly orders
72
+ let userFriendlyOrders: Order[] = new Array<Order>();
73
+ let k = 0;
74
+ while (k < orders.length && orders[k].traderAddr != ZERO_ADDRESS) {
75
+ userFriendlyOrders.push(PerpetualDataHandler.fromSmartContractOrder(orders[k], this.symbolToPerpStaticInfo));
76
+ k++;
77
+ }
78
+ return userFriendlyOrders;
79
+ }
80
+
81
+ /**
82
+ *
83
+ * @param traderAddr address of the trader
84
+ * @param orderBookContract instance of order book contract
85
+ * @returns array of order-id's
86
+ */
87
+ protected async orderIdsOfTrader(traderAddr: string, orderBookContract: ethers.Contract): Promise<string[]> {
88
+ let digestsRaw: string[] = await orderBookContract.limitDigestsOfTrader(traderAddr, 0, 15);
89
+ let k: number = 0;
90
+ let digests: string[] = [];
91
+ while (k < digestsRaw.length && BigNumber.from(digestsRaw[k]).gt(0)) {
92
+ digests.push(digestsRaw[k]);
93
+ k++;
94
+ }
95
+ return digests;
96
+ }
97
+
98
+ public static async _exchangeInfo(_proxyContract: ethers.Contract): Promise<ExchangeInfo> {
99
+ let nestedPerpetualIDs = await PerpetualDataHandler.getNestedPerpetualIds(_proxyContract);
100
+ let info: ExchangeInfo = { pools: [] };
101
+ const numPools = nestedPerpetualIDs.length;
102
+ for (var j = 0; j < numPools; j++) {
103
+ let perpetualIDs = nestedPerpetualIDs[j];
104
+ let pool = await _proxyContract.getLiquidityPool(j + 1);
105
+ let PoolState: PoolState = {
106
+ isRunning: pool.isRunning,
107
+ marginTokenAddr: pool.marginTokenAddress,
108
+ poolShareTokenAddr: pool.shareTokenAddress,
109
+ defaultFundCashCC: ABK64x64ToFloat(pool.fDefaultFundCashCC),
110
+ pnlParticipantCashCC: ABK64x64ToFloat(pool.fPnLparticipantsCashCC),
111
+ totalAMMFundCashCC: ABK64x64ToFloat(pool.fAMMFundCashCC),
112
+ totalTargetAMMFundSizeCC: ABK64x64ToFloat(pool.fTargetAMMFundSize),
113
+ brokerCollateralLotSize: ABK64x64ToFloat(pool.fBrokerCollateralLotSize),
114
+ perpetuals: [],
115
+ };
116
+ for (var k = 0; k < perpetualIDs.length; k++) {
117
+ let perp = await _proxyContract.getPerpetual(perpetualIDs[k]);
118
+ let fIndexS2 = await _proxyContract.getOraclePrice([perp.S2BaseCCY, perp.S2QuoteCCY]);
119
+ let indexS2 = ABK64x64ToFloat(fIndexS2);
120
+ let indexS3 = 1;
121
+ if (perp.eCollateralCurrency == COLLATERAL_CURRENCY_BASE) {
122
+ indexS3 = indexS2;
123
+ } else if (perp.eCollateralCurrency == COLLATERAL_CURRENCY_QUANTO) {
124
+ indexS3 = ABK64x64ToFloat(await _proxyContract.getOraclePrice([perp.S3BaseCCY, perp.S3QuoteCCY]));
125
+ }
126
+ let markPremiumRate = ABK64x64ToFloat(perp.currentMarkPremiumRate.fPrice);
127
+ let currentFundingRateBps = 1e4 * ABK64x64ToFloat(perp.fCurrentFundingRate);
128
+ let state = PERP_STATE_STR[perp.state];
129
+ let PerpetualState: PerpetualState = {
130
+ id: perp.id,
131
+ state: state,
132
+ baseCurrency: fromBytes4HexString(perp.S2BaseCCY),
133
+ quoteCurrency: fromBytes4HexString(perp.S2QuoteCCY),
134
+ indexPrice: indexS2,
135
+ collToQuoteIndexPrice: indexS3,
136
+ markPrice: indexS2 * (1 + markPremiumRate),
137
+ currentFundingRateBps: currentFundingRateBps,
138
+ initialMarginRate: ABK64x64ToFloat(perp.fInitialMarginRate),
139
+ maintenanceMarginRate: ABK64x64ToFloat(perp.fMaintenanceMarginRate),
140
+ openInterestBC: ABK64x64ToFloat(perp.fOpenInterest),
141
+ maxPositionBC: ABK64x64ToFloat(perp.fMaxPositionBC),
142
+ };
143
+ PoolState.perpetuals.push(PerpetualState);
144
+ }
145
+ info.pools.push(PoolState);
146
+ }
147
+ return info;
148
+ }
149
+ }
@@ -0,0 +1,158 @@
1
+ import { BytesLike, BigNumber, BigNumberish } from "ethers";
2
+ export const DEFAULT_CONFIG_TESTNET = "../config/defaultConfig.json";
3
+ export const DEFAULT_CONFIG_MAINNET = "notthereyet";
4
+ export const DEFAULT_CONFIG_TESTNET_NAME = "testnet";
5
+ export const DEFAULT_CONFIG_MAINNET_NAME = "mainnet";
6
+
7
+ export const ERC20_ABI = require("../abi/ERC20.json");
8
+ export const COLLATERAL_CURRENCY_QUOTE = 0;
9
+ export const COLLATERAL_CURRENCY_BASE = 1;
10
+ export const COLLATERAL_CURRENCY_QUANTO = 2;
11
+ export const PERP_STATE_STR = ["INVALID", "INITIALIZING", "NORMAL", "EMERGENCY", "CLEARED"];
12
+ export const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
13
+
14
+ export const ONE_64x64 = BigNumber.from("0x010000000000000000");
15
+ export const MAX_64x64 = BigNumber.from("0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
16
+ export const MAX_UINT_256 = BigNumber.from(2).pow(256).sub(BigNumber.from(1));
17
+ export const DECIMALS = BigNumber.from(10).pow(BigNumber.from(18));
18
+
19
+ export const ORDER_MAX_DURATION_SEC = 60 * 60 * 24 * 30 * 4;
20
+
21
+ export const MASK_CLOSE_ONLY = BigNumber.from("0x80000000");
22
+ export const MASK_LIMIT_ORDER = BigNumber.from("0x04000000");
23
+ export const MASK_MARKET_ORDER = BigNumber.from("0x40000000");
24
+ export const MASK_STOP_ORDER = BigNumber.from("0x20000000");
25
+ export const MASK_KEEP_POS_LEVERAGE = BigNumber.from("0x08000000");
26
+
27
+ export const ORDER_TYPE_LIMIT = "LIMIT";
28
+ export const ORDER_TYPE_MARKET = "MARKET";
29
+ export const ORDER_TYPE_STOP_MARKET = "STOP_MARKET";
30
+ export const ORDER_TYPE_STOP_LIMIT = "STOP_LIMIT";
31
+ export const BUY_SIDE = "BUY";
32
+ export const SELL_SIDE = "SELL";
33
+ export const CLOSED_SIDE = "CLOSED";
34
+ export interface NodeSDKConfig {
35
+ nodeURL: string;
36
+ proxyAddr: string;
37
+ proxyABILocation: string;
38
+ limitOrderBookFactoryAddr: string;
39
+ limitOrderBookABILocation: string;
40
+ limitOrderBookFactoryABILocation: string;
41
+ gasLimit?: number | undefined;
42
+ }
43
+
44
+ export interface MarginAccount {
45
+ symbol: string;
46
+ positionNotionalBaseCCY: number;
47
+ side: string;
48
+ entryPrice: number;
49
+ leverage: number;
50
+ markPrice: number;
51
+ unrealizedPnlQuoteCCY: number;
52
+ unrealizedFundingCollateralCCY: number;
53
+ collateralCC: number;
54
+ liquidationPrice: [number, number | undefined];
55
+ liquidationLvg: number;
56
+ collToQuoteConversion: number;
57
+ }
58
+
59
+ export enum CollaterlCCY {
60
+ QUOTE = 0,
61
+ BASE,
62
+ QUANTO,
63
+ }
64
+
65
+ export interface PoolStaticInfo {
66
+ poolId: number;
67
+ poolMarginSymbol: string;
68
+ poolMarginTokenAddr: string;
69
+ shareTokenAddr: string;
70
+ oracleFactoryAddr: string;
71
+ }
72
+
73
+ export interface PerpetualStaticInfo {
74
+ id: number;
75
+ limitOrderBookAddr: string;
76
+ maintenanceMarginRate: number;
77
+ collateralCurrencyType: CollaterlCCY;
78
+ S2Symbol: string;
79
+ S3Symbol: string;
80
+ }
81
+
82
+ export interface ExchangeInfo {
83
+ pools: PoolState[];
84
+ }
85
+ export interface PoolState {
86
+ isRunning: boolean;
87
+ marginTokenAddr: string;
88
+ poolShareTokenAddr: string;
89
+ defaultFundCashCC: number;
90
+ pnlParticipantCashCC: number;
91
+ totalAMMFundCashCC: number;
92
+ totalTargetAMMFundSizeCC: number;
93
+ brokerCollateralLotSize: number;
94
+ perpetuals: PerpetualState[];
95
+ }
96
+
97
+ export interface PerpetualState {
98
+ id: number;
99
+ state: string;
100
+ baseCurrency: string;
101
+ quoteCurrency: string;
102
+ indexPrice: number;
103
+ collToQuoteIndexPrice: number;
104
+ markPrice: number;
105
+ currentFundingRateBps: number;
106
+ initialMarginRate: number;
107
+ maintenanceMarginRate: number;
108
+ openInterestBC: number;
109
+ maxPositionBC: number;
110
+ }
111
+
112
+ export interface Order {
113
+ symbol: string;
114
+ side: string;
115
+ type: string;
116
+ quantity: number;
117
+ reduceOnly?: boolean | undefined;
118
+ limitPrice?: number | undefined;
119
+ keepPositionLvg?: boolean | undefined;
120
+ brokerFeeTbps?: number | undefined;
121
+ brokerAddr?: string | undefined;
122
+ brokerSignature?: BytesLike | undefined;
123
+ stopPrice?: number | undefined;
124
+ leverage?: number | undefined;
125
+ deadline?: number | undefined;
126
+ timestamp: number;
127
+ }
128
+
129
+ export interface SmartContractOrder {
130
+ flags: BigNumberish;
131
+ iPerpetualId: BigNumberish;
132
+ brokerFeeTbps: BigNumberish;
133
+ traderAddr: string;
134
+ brokerAddr: string;
135
+ referrerAddr: string;
136
+ brokerSignature: BytesLike;
137
+ fAmount: BigNumberish;
138
+ fLimitPrice: BigNumberish;
139
+ fTriggerPrice: BigNumberish;
140
+ fLeverage: BigNumberish;
141
+ iDeadline: BigNumberish;
142
+ createdTimestamp: BigNumberish;
143
+ }
144
+ /*
145
+ t32 flags;
146
+ uint24 iPerpetualId;
147
+ uint16 brokerFeeTbps;
148
+ address traderAddr;
149
+ address brokerAddr;
150
+ address referrerAddr;
151
+ bytes brokerSignature;
152
+ int128 fAmount;
153
+ int128 fLimitPrice;
154
+ int128 fTriggerPrice;
155
+ int128 fLeverage; // 0 if deposit and trade separate
156
+ uint256 iDeadline;
157
+ uint256 createdTimestamp;
158
+ */
@@ -0,0 +1,17 @@
1
+ import WriteAccessHandler from "./writeAccessHandler";
2
+ import { NodeSDKConfig } from "./nodeSDKTypes";
3
+
4
+ /**
5
+ * OrderReferrerTool
6
+ * Methods to refer orders from the limit order book
7
+ */
8
+ export default class OrderReferrerTool extends WriteAccessHandler {
9
+ /**
10
+ * Constructor
11
+ * @param config configuration
12
+ * @param privateKey private key of account that trades
13
+ */
14
+ public constructor(config: NodeSDKConfig, privateKey: string) {
15
+ super(config, privateKey);
16
+ }
17
+ }