@d8x/perpetuals-sdk 0.0.2 → 0.0.3

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.
@@ -35,6 +35,13 @@ export default class AccountTrade extends WriteAccessHandler {
35
35
  * @returns Exchange fee, in decimals (i.e. 0.1% is 0.001).
36
36
  */
37
37
  queryExchangeFee(poolSymbolName: string, brokerAddr?: string): Promise<number>;
38
+ /**
39
+ * Exponentially weighted EMA of the total trading volume of all trades performed by this trader.
40
+ * The weights are chosen so that in average this coincides with the 30 day volume.
41
+ * @param {string} poolSymbolName Pool symbol name (e.g. MATIC, USDC, etc).
42
+ * @returns {number} Current trading volume for this trader, in USD.
43
+ */
44
+ getCurrentTraderVolume(poolSymbolName: string): Promise<number>;
38
45
  /**
39
46
  * Static order function
40
47
  * @param order order type (not SmartContractOrder but Order)
@@ -13,6 +13,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  const ethers_1 = require("ethers");
16
+ const d8XMath_1 = require("./d8XMath");
16
17
  const nodeSDKTypes_1 = require("./nodeSDKTypes");
17
18
  const writeAccessHandler_1 = __importDefault(require("./writeAccessHandler"));
18
19
  /**
@@ -88,6 +89,22 @@ class AccountTrade extends writeAccessHandler_1.default {
88
89
  return feeTbps / 100000;
89
90
  });
90
91
  }
92
+ /**
93
+ * Exponentially weighted EMA of the total trading volume of all trades performed by this trader.
94
+ * The weights are chosen so that in average this coincides with the 30 day volume.
95
+ * @param {string} poolSymbolName Pool symbol name (e.g. MATIC, USDC, etc).
96
+ * @returns {number} Current trading volume for this trader, in USD.
97
+ */
98
+ getCurrentTraderVolume(poolSymbolName) {
99
+ return __awaiter(this, void 0, void 0, function* () {
100
+ if (this.proxyContract == null || this.signer == null) {
101
+ throw Error("no proxy contract or wallet initialized. Use createProxyInstance().");
102
+ }
103
+ let poolId = writeAccessHandler_1.default._getPoolIdFromSymbol(poolSymbolName, this.poolStaticInfos);
104
+ let volume = yield this.proxyContract.getCurrentTraderVolume(poolId, this.traderAddr);
105
+ return (0, d8XMath_1.ABK64x64ToFloat)(volume);
106
+ });
107
+ }
91
108
  /**
92
109
  * Static order function
93
110
  * @param order order type (not SmartContractOrder but Order)
@@ -11,35 +11,20 @@ export default class BrokerTool extends WriteAccessHandler {
11
11
  * @param {string} privateKey Private key of a broker.
12
12
  */
13
13
  constructor(config: NodeSDKConfig, privateKey: string);
14
- getBrokerInducedFee(poolSymbolName: string): Promise<number>;
15
- /**
16
- * Total amount of collateral currency a broker has to deposit into the default fund to purchase one lot.
17
- * This is equivalent to the price of a lot expressed in a given pool's currency (e.g. MATIC, USDC, etc).
18
- * @param {string} poolSymbolName Pool symbol name (e.g. MATIC, USDC, etc).
19
- * @returns Broker lot size in a given pool's currency, e.g. in MATIC for poolSymbolName MATIC.
20
- */
21
- getLotSize(poolSymbolName: string): Promise<number>;
22
14
  /**
23
- * Provides information on how many lots a broker purchased for a given pool.
24
- * This is relevant to determine the broker's fee tier.
15
+ * Determine the exchange fee based on lots, traded volume, and D8X balance of this broker.
16
+ * This is the final exchange fee paid by the broker.
25
17
  * @param {string} poolSymbolName Pool symbol name (e.g. MATIC, USDC, etc).
26
- * @returns Number of lots purchased by this broker.
18
+ * @returns {number} Exchange fee for this broker, in decimals (i.e. 0.1% is 0.001)
27
19
  */
28
- getBrokerDesignation(poolSymbolName: string): Promise<number>;
29
- /**
30
- * Deposit lots to the default fund of a given pool.
31
- * @param {string} poolSymbolName Pool symbol name (e.g. MATIC, USDC, etc).
32
- * @param lots Number of lots to deposit into this pool.
33
- * @returns Transaction object.
34
- */
35
- brokerDepositToDefaultFund(poolSymbolName: string, lots: number): Promise<ethers.providers.TransactionResponse>;
20
+ getBrokerInducedFee(poolSymbolName: string): Promise<number>;
36
21
  /**
37
22
  * Determine the exchange fee based on lots purchased by this broker.
38
23
  * The final exchange fee paid by the broker is equal to
39
24
  * maximum(brokerTool.getFeeForBrokerDesignation(poolSymbolName), brokerTool.getFeeForBrokerVolume(poolSymbolName), brokerTool.getFeeForBrokerStake())
40
25
  * @param {string} poolSymbolName Pool symbol name (e.g. MATIC, USDC, etc).
41
- * @param {number} lots Optional, designation to use if different from this broker's.
42
- * @returns Fee based solely on this broker's designation, in decimals (i.e. 0.1% is 0.001).
26
+ * @param {number=} lots Optional, designation to use if different from this broker's.
27
+ * @returns {number} Fee based solely on this broker's designation, in decimals (i.e. 0.1% is 0.001).
43
28
  */
44
29
  getFeeForBrokerDesignation(poolSymbolName: string, lots?: number): Promise<number>;
45
30
  /**
@@ -47,15 +32,15 @@ export default class BrokerTool extends WriteAccessHandler {
47
32
  * The final exchange fee paid by the broker is equal to
48
33
  * maximum(brokerTool.getFeeForBrokerDesignation(poolSymbolName), brokerTool.getFeeForBrokerVolume(poolSymbolName), brokerTool.getFeeForBrokerStake())
49
34
  * @param {string} poolSymbolName Pool symbol name (e.g. MATIC, USDC, etc).
50
- * @returns Fee based solely on a broker's traded volume in the corresponding pool, in decimals (i.e. 0.1% is 0.001).
35
+ * @returns {number} Fee based solely on a broker's traded volume in the corresponding pool, in decimals (i.e. 0.1% is 0.001).
51
36
  */
52
- getFeeForBrokerVolume(poolSymbolName: string): Promise<number | undefined>;
37
+ getFeeForBrokerVolume(poolSymbolName: string): Promise<number>;
53
38
  /**
54
39
  * Determine the exchange fee based on the current D8X balance in a broker's wallet.
55
40
  * The final exchange fee paid by the broker is equal to
56
41
  * maximum(brokerTool.getFeeForBrokerDesignation(symbol, lots), brokerTool.getFeeForBrokerVolume(symbol), brokerTool.getFeeForBrokerStake)
57
42
  * @param {string=} brokerAddr Address of the broker in question, if different from the one calling this function.
58
- * @returns Fee based solely on a broker's D8X balance, in decimals (i.e. 0.1% is 0.001).
43
+ * @returns {number} Fee based solely on a broker's D8X balance, in decimals (i.e. 0.1% is 0.001).
59
44
  */
60
45
  getFeeForBrokerStake(brokerAddr?: string): Promise<number>;
61
46
  /**
@@ -64,18 +49,47 @@ export default class BrokerTool extends WriteAccessHandler {
64
49
  * and it takes into account whether the order given here has been signed by a broker or not.
65
50
  * Use this, for instance, to verify that the fee to be charged for a given order is as expected,
66
51
  * before and after signing it with brokerTool.signOrder.
52
+ * This fee is equal or lower than the broker induced fee, provided the order is properly signed.
67
53
  * @param {Order} order Order for which to determine the exchange fee. Not necessarily signed by this broker.
68
54
  * @param {string} traderAddr Address of the trader for whom to determine the fee.
69
- * @returns Fee in decimals (i.e. 0.1% is 0.001).
55
+ * @returns {number} Fee in decimals (i.e. 0.1% is 0.001).
70
56
  */
71
57
  determineExchangeFee(order: Order, traderAddr: string): Promise<number>;
58
+ /**
59
+ * Exponentially weighted EMA of the total trading volume of all trades performed under this broker.
60
+ * The weights are chosen so that in average this coincides with the 30 day volume.
61
+ * @param {string} poolSymbolName Pool symbol name (e.g. MATIC, USDC, etc).
62
+ * @returns {number} Current trading volume for this broker, in USD.
63
+ */
64
+ getCurrentBrokerVolume(poolSymbolName: string): Promise<number>;
65
+ /**
66
+ * Total amount of collateral currency a broker has to deposit into the default fund to purchase one lot.
67
+ * This is equivalent to the price of a lot expressed in a given pool's currency (e.g. MATIC, USDC, etc).
68
+ * @param {string} poolSymbolName Pool symbol name (e.g. MATIC, USDC, etc).
69
+ * @returns {number} Broker lot size in a given pool's currency, e.g. in MATIC for poolSymbolName MATIC.
70
+ */
71
+ getLotSize(poolSymbolName: string): Promise<number>;
72
+ /**
73
+ * Provides information on how many lots a broker purchased for a given pool.
74
+ * This is relevant to determine the broker's fee tier.
75
+ * @param {string} poolSymbolName Pool symbol name (e.g. MATIC, USDC, etc).
76
+ * @returns {number} Number of lots purchased by this broker.
77
+ */
78
+ getBrokerDesignation(poolSymbolName: string): Promise<number>;
79
+ /**
80
+ * Deposit lots to the default fund of a given pool.
81
+ * @param {string} poolSymbolName Pool symbol name (e.g. MATIC, USDC, etc).
82
+ * @param {number} lots Number of lots to deposit into this pool.
83
+ * @returns {ethers.providers.TransactionResponse} Transaction object.
84
+ */
85
+ brokerDepositToDefaultFund(poolSymbolName: string, lots: number): Promise<ethers.providers.TransactionResponse>;
72
86
  /**
73
87
  * Adds this broker's signature to an order so that it can be submitted by an approved trader.
74
88
  * @param {Order} order Order to sign.
75
89
  * @param {string} traderAddr Address of trader submitting the order.
76
90
  * @param {number} feeDecimals Fee that this broker is approving for the trader.
77
91
  * @param {number} deadline Deadline for the order to be executed.
78
- * @returns An order signed by this broker, which can be submitted directly with AccountTrade.order.
92
+ * @returns {Order} An order signed by this broker, which can be submitted directly with AccountTrade.order.
79
93
  */
80
94
  signOrder(order: Order, traderAddr: string, brokerFee: number, deadline: number): Promise<Order>;
81
95
  /**
@@ -85,16 +99,16 @@ export default class BrokerTool extends WriteAccessHandler {
85
99
  * @param {string} symbol Perpetual that this trader will be trading, of the form ETH-USD-MATIC.
86
100
  * @param {number} brokerFee Broker fee for this trader, in decimals (i.e. 0.1% is 0.001).
87
101
  * @param {number} deadline Deadline for the order to be executed.
88
- * @returns Broker signature approving this trader's fee, symbol, and deadline.
102
+ * @returns {string} Broker signature approving this trader's fee, symbol, and deadline.
89
103
  * @ignore
90
104
  */
91
105
  createSignatureForTrader(traderAddr: string, symbol: string, brokerFee: number, deadline: number): Promise<string>;
92
106
  static _signOrder(symbol: string, brokerFeeTbps: number, traderAddr: string, iDeadline: BigNumber, signer: ethers.Wallet, chainId: number, proxyAddress: string, symbolToPerpStaticInfo: Map<string, PerpetualStaticInfo>): Promise<string>;
93
107
  /**
94
108
  * Transfer ownership of a broker's status to a new wallet.
95
- * @param poolSymbolName Symbol refers to the pool (e.g., MATIC for the MATIC-pool)
96
- * @param newAddress The address this broker wants to use from now on.
97
- * @returns ethers transaction object
109
+ * @param {string} poolSymbolName Pool symbol name (e.g. MATIC, USDC, etc).
110
+ * @param {string} newAddress The address this broker wants to use from now on.
111
+ * @returns {ethers.providers.TransactionResponse} ethers transaction object
98
112
  */
99
113
  transferOwnership(poolSymbolName: string, newAddress: string): Promise<ethers.providers.TransactionResponse>;
100
114
  }
@@ -29,63 +29,21 @@ class BrokerTool extends writeAccessHandler_1.default {
29
29
  constructor(config, privateKey) {
30
30
  super(config, privateKey);
31
31
  }
32
- getBrokerInducedFee(poolSymbolName) {
33
- return __awaiter(this, void 0, void 0, function* () {
34
- if (this.proxyContract == null || this.signer == null) {
35
- throw Error("no proxy contract or wallet initialized. Use createProxyInstance().");
36
- }
37
- let poolId = perpetualDataHandler_1.default._getPoolIdFromSymbol(poolSymbolName, this.poolStaticInfos);
38
- let feeTbps = yield this.proxyContract.getBrokerInducedFee(poolId, this.traderAddr);
39
- return feeTbps / 100000;
40
- });
41
- }
42
- /**
43
- * Total amount of collateral currency a broker has to deposit into the default fund to purchase one lot.
44
- * This is equivalent to the price of a lot expressed in a given pool's currency (e.g. MATIC, USDC, etc).
45
- * @param {string} poolSymbolName Pool symbol name (e.g. MATIC, USDC, etc).
46
- * @returns Broker lot size in a given pool's currency, e.g. in MATIC for poolSymbolName MATIC.
47
- */
48
- getLotSize(poolSymbolName) {
49
- return __awaiter(this, void 0, void 0, function* () {
50
- if (this.proxyContract == null) {
51
- throw Error("no proxy contract initialized. Use createProxyInstance().");
52
- }
53
- let poolId = perpetualDataHandler_1.default._getPoolIdFromSymbol(poolSymbolName, this.poolStaticInfos);
54
- let pool = yield this.proxyContract.getLiquidityPool(poolId);
55
- let lot = (0, d8XMath_1.ABK64x64ToFloat)(pool.fBrokerCollateralLotSize);
56
- return lot;
57
- });
58
- }
32
+ // Fee getters
59
33
  /**
60
- * Provides information on how many lots a broker purchased for a given pool.
61
- * This is relevant to determine the broker's fee tier.
62
- * @param {string} poolSymbolName Pool symbol name (e.g. MATIC, USDC, etc).
63
- * @returns Number of lots purchased by this broker.
64
- */
65
- getBrokerDesignation(poolSymbolName) {
66
- return __awaiter(this, void 0, void 0, function* () {
67
- if (this.proxyContract == null || this.signer == null) {
68
- throw Error("no proxy contract or wallet initialized. Use createProxyInstance().");
69
- }
70
- let poolId = perpetualDataHandler_1.default._getPoolIdFromSymbol(poolSymbolName, this.poolStaticInfos);
71
- let designation = yield this.proxyContract.getBrokerDesignation(poolId, this.traderAddr);
72
- return designation;
73
- });
74
- }
75
- /**
76
- * Deposit lots to the default fund of a given pool.
34
+ * Determine the exchange fee based on lots, traded volume, and D8X balance of this broker.
35
+ * This is the final exchange fee paid by the broker.
77
36
  * @param {string} poolSymbolName Pool symbol name (e.g. MATIC, USDC, etc).
78
- * @param lots Number of lots to deposit into this pool.
79
- * @returns Transaction object.
37
+ * @returns {number} Exchange fee for this broker, in decimals (i.e. 0.1% is 0.001)
80
38
  */
81
- brokerDepositToDefaultFund(poolSymbolName, lots) {
39
+ getBrokerInducedFee(poolSymbolName) {
82
40
  return __awaiter(this, void 0, void 0, function* () {
83
41
  if (this.proxyContract == null || this.signer == null) {
84
42
  throw Error("no proxy contract or wallet initialized. Use createProxyInstance().");
85
43
  }
86
44
  let poolId = perpetualDataHandler_1.default._getPoolIdFromSymbol(poolSymbolName, this.poolStaticInfos);
87
- let tx = yield this.proxyContract.brokerDepositToDefaultFund(poolId, lots, { gasLimit: this.gasLimit });
88
- return tx;
45
+ let feeTbps = yield this.proxyContract.getBrokerInducedFee(poolId, this.traderAddr);
46
+ return feeTbps / 100000;
89
47
  });
90
48
  }
91
49
  /**
@@ -93,8 +51,8 @@ class BrokerTool extends writeAccessHandler_1.default {
93
51
  * The final exchange fee paid by the broker is equal to
94
52
  * maximum(brokerTool.getFeeForBrokerDesignation(poolSymbolName), brokerTool.getFeeForBrokerVolume(poolSymbolName), brokerTool.getFeeForBrokerStake())
95
53
  * @param {string} poolSymbolName Pool symbol name (e.g. MATIC, USDC, etc).
96
- * @param {number} lots Optional, designation to use if different from this broker's.
97
- * @returns Fee based solely on this broker's designation, in decimals (i.e. 0.1% is 0.001).
54
+ * @param {number=} lots Optional, designation to use if different from this broker's.
55
+ * @returns {number} Fee based solely on this broker's designation, in decimals (i.e. 0.1% is 0.001).
98
56
  */
99
57
  getFeeForBrokerDesignation(poolSymbolName, lots) {
100
58
  return __awaiter(this, void 0, void 0, function* () {
@@ -118,7 +76,7 @@ class BrokerTool extends writeAccessHandler_1.default {
118
76
  * The final exchange fee paid by the broker is equal to
119
77
  * maximum(brokerTool.getFeeForBrokerDesignation(poolSymbolName), brokerTool.getFeeForBrokerVolume(poolSymbolName), brokerTool.getFeeForBrokerStake())
120
78
  * @param {string} poolSymbolName Pool symbol name (e.g. MATIC, USDC, etc).
121
- * @returns Fee based solely on a broker's traded volume in the corresponding pool, in decimals (i.e. 0.1% is 0.001).
79
+ * @returns {number} Fee based solely on a broker's traded volume in the corresponding pool, in decimals (i.e. 0.1% is 0.001).
122
80
  */
123
81
  getFeeForBrokerVolume(poolSymbolName) {
124
82
  return __awaiter(this, void 0, void 0, function* () {
@@ -135,7 +93,7 @@ class BrokerTool extends writeAccessHandler_1.default {
135
93
  * The final exchange fee paid by the broker is equal to
136
94
  * maximum(brokerTool.getFeeForBrokerDesignation(symbol, lots), brokerTool.getFeeForBrokerVolume(symbol), brokerTool.getFeeForBrokerStake)
137
95
  * @param {string=} brokerAddr Address of the broker in question, if different from the one calling this function.
138
- * @returns Fee based solely on a broker's D8X balance, in decimals (i.e. 0.1% is 0.001).
96
+ * @returns {number} Fee based solely on a broker's D8X balance, in decimals (i.e. 0.1% is 0.001).
139
97
  */
140
98
  getFeeForBrokerStake(brokerAddr) {
141
99
  return __awaiter(this, void 0, void 0, function* () {
@@ -155,9 +113,10 @@ class BrokerTool extends writeAccessHandler_1.default {
155
113
  * and it takes into account whether the order given here has been signed by a broker or not.
156
114
  * Use this, for instance, to verify that the fee to be charged for a given order is as expected,
157
115
  * before and after signing it with brokerTool.signOrder.
116
+ * This fee is equal or lower than the broker induced fee, provided the order is properly signed.
158
117
  * @param {Order} order Order for which to determine the exchange fee. Not necessarily signed by this broker.
159
118
  * @param {string} traderAddr Address of the trader for whom to determine the fee.
160
- * @returns Fee in decimals (i.e. 0.1% is 0.001).
119
+ * @returns {number} Fee in decimals (i.e. 0.1% is 0.001).
161
120
  */
162
121
  determineExchangeFee(order, traderAddr) {
163
122
  return __awaiter(this, void 0, void 0, function* () {
@@ -169,13 +128,81 @@ class BrokerTool extends writeAccessHandler_1.default {
169
128
  return feeTbps / 100000;
170
129
  });
171
130
  }
131
+ // Volume
132
+ /**
133
+ * Exponentially weighted EMA of the total trading volume of all trades performed under this broker.
134
+ * The weights are chosen so that in average this coincides with the 30 day volume.
135
+ * @param {string} poolSymbolName Pool symbol name (e.g. MATIC, USDC, etc).
136
+ * @returns {number} Current trading volume for this broker, in USD.
137
+ */
138
+ getCurrentBrokerVolume(poolSymbolName) {
139
+ return __awaiter(this, void 0, void 0, function* () {
140
+ if (this.proxyContract == null || this.signer == null) {
141
+ throw Error("no proxy contract or wallet initialized. Use createProxyInstance().");
142
+ }
143
+ let poolId = perpetualDataHandler_1.default._getPoolIdFromSymbol(poolSymbolName, this.poolStaticInfos);
144
+ let volume = yield this.proxyContract.getCurrentBrokerVolume(poolId, this.traderAddr);
145
+ return (0, d8XMath_1.ABK64x64ToFloat)(volume);
146
+ });
147
+ }
148
+ // Lots
149
+ /**
150
+ * Total amount of collateral currency a broker has to deposit into the default fund to purchase one lot.
151
+ * This is equivalent to the price of a lot expressed in a given pool's currency (e.g. MATIC, USDC, etc).
152
+ * @param {string} poolSymbolName Pool symbol name (e.g. MATIC, USDC, etc).
153
+ * @returns {number} Broker lot size in a given pool's currency, e.g. in MATIC for poolSymbolName MATIC.
154
+ */
155
+ getLotSize(poolSymbolName) {
156
+ return __awaiter(this, void 0, void 0, function* () {
157
+ if (this.proxyContract == null) {
158
+ throw Error("no proxy contract initialized. Use createProxyInstance().");
159
+ }
160
+ let poolId = perpetualDataHandler_1.default._getPoolIdFromSymbol(poolSymbolName, this.poolStaticInfos);
161
+ let pool = yield this.proxyContract.getLiquidityPool(poolId);
162
+ let lot = (0, d8XMath_1.ABK64x64ToFloat)(pool.fBrokerCollateralLotSize);
163
+ return lot;
164
+ });
165
+ }
166
+ /**
167
+ * Provides information on how many lots a broker purchased for a given pool.
168
+ * This is relevant to determine the broker's fee tier.
169
+ * @param {string} poolSymbolName Pool symbol name (e.g. MATIC, USDC, etc).
170
+ * @returns {number} Number of lots purchased by this broker.
171
+ */
172
+ getBrokerDesignation(poolSymbolName) {
173
+ return __awaiter(this, void 0, void 0, function* () {
174
+ if (this.proxyContract == null || this.signer == null) {
175
+ throw Error("no proxy contract or wallet initialized. Use createProxyInstance().");
176
+ }
177
+ let poolId = perpetualDataHandler_1.default._getPoolIdFromSymbol(poolSymbolName, this.poolStaticInfos);
178
+ let designation = yield this.proxyContract.getBrokerDesignation(poolId, this.traderAddr);
179
+ return designation;
180
+ });
181
+ }
182
+ /**
183
+ * Deposit lots to the default fund of a given pool.
184
+ * @param {string} poolSymbolName Pool symbol name (e.g. MATIC, USDC, etc).
185
+ * @param {number} lots Number of lots to deposit into this pool.
186
+ * @returns {ethers.providers.TransactionResponse} Transaction object.
187
+ */
188
+ brokerDepositToDefaultFund(poolSymbolName, lots) {
189
+ return __awaiter(this, void 0, void 0, function* () {
190
+ if (this.proxyContract == null || this.signer == null) {
191
+ throw Error("no proxy contract or wallet initialized. Use createProxyInstance().");
192
+ }
193
+ let poolId = perpetualDataHandler_1.default._getPoolIdFromSymbol(poolSymbolName, this.poolStaticInfos);
194
+ let tx = yield this.proxyContract.brokerDepositToDefaultFund(poolId, lots, { gasLimit: this.gasLimit });
195
+ return tx;
196
+ });
197
+ }
198
+ // Signatures
172
199
  /**
173
200
  * Adds this broker's signature to an order so that it can be submitted by an approved trader.
174
201
  * @param {Order} order Order to sign.
175
202
  * @param {string} traderAddr Address of trader submitting the order.
176
203
  * @param {number} feeDecimals Fee that this broker is approving for the trader.
177
204
  * @param {number} deadline Deadline for the order to be executed.
178
- * @returns An order signed by this broker, which can be submitted directly with AccountTrade.order.
205
+ * @returns {Order} An order signed by this broker, which can be submitted directly with AccountTrade.order.
179
206
  */
180
207
  signOrder(order, traderAddr, brokerFee, deadline) {
181
208
  return __awaiter(this, void 0, void 0, function* () {
@@ -196,7 +223,7 @@ class BrokerTool extends writeAccessHandler_1.default {
196
223
  * @param {string} symbol Perpetual that this trader will be trading, of the form ETH-USD-MATIC.
197
224
  * @param {number} brokerFee Broker fee for this trader, in decimals (i.e. 0.1% is 0.001).
198
225
  * @param {number} deadline Deadline for the order to be executed.
199
- * @returns Broker signature approving this trader's fee, symbol, and deadline.
226
+ * @returns {string} Broker signature approving this trader's fee, symbol, and deadline.
200
227
  * @ignore
201
228
  */
202
229
  createSignatureForTrader(traderAddr, symbol, brokerFee, deadline) {
@@ -224,11 +251,12 @@ class BrokerTool extends writeAccessHandler_1.default {
224
251
  return yield signer.signMessage(digestBuffer);
225
252
  });
226
253
  }
254
+ // Transfer ownership
227
255
  /**
228
256
  * Transfer ownership of a broker's status to a new wallet.
229
- * @param poolSymbolName Symbol refers to the pool (e.g., MATIC for the MATIC-pool)
230
- * @param newAddress The address this broker wants to use from now on.
231
- * @returns ethers transaction object
257
+ * @param {string} poolSymbolName Pool symbol name (e.g. MATIC, USDC, etc).
258
+ * @param {string} newAddress The address this broker wants to use from now on.
259
+ * @returns {ethers.providers.TransactionResponse} ethers transaction object
232
260
  */
233
261
  transferOwnership(poolSymbolName, newAddress) {
234
262
  return __awaiter(this, void 0, void 0, function* () {
@@ -35,4 +35,24 @@ export default class LiquidatorTool extends WriteAccessHandler {
35
35
  * @ignore
36
36
  */
37
37
  _liquidateByAMM(perpetualId: number, liquidatorAddr: string, traderAddr: string, gasLimit: number): Promise<number>;
38
+ /**
39
+ * Total number of active accounts for this symbol, i.e. accounts with positions that are currently open.
40
+ * @param {string} symbol Symbol of the form ETH-USD-MATIC.
41
+ * @returns {number} Number of active accounts.
42
+ */
43
+ countActivePerpAccounts(symbol: string): Promise<number>;
44
+ /**
45
+ * Get addresses of active accounts by chunks.
46
+ * @param {string} symbol Symbol of the form ETH-USD-MATIC.
47
+ * @param {number} from From which account we start counting (0-indexed).
48
+ * @param {number} to Until which account we count, non inclusive.
49
+ * @returns {string[]} Array of addresses at locations 'from', 'from'+1 ,..., 'to'-1.
50
+ */
51
+ getActiveAccountsByChunks(symbol: string, from: number, to: number): Promise<string[]>;
52
+ /**
53
+ * Addresses for all the active accounts in this perpetual symbol.
54
+ * @param {string} symbol Symbol of the form ETH-USD-MATIC.
55
+ * @returns {string[]} Array of addresses.
56
+ */
57
+ getAllActiveAccounts(symbol: string): Promise<string[]>;
38
58
  }
@@ -60,7 +60,7 @@ class LiquidatorTool extends writeAccessHandler_1.default {
60
60
  throw Error("no proxy contract initialized. Use createProxyInstance().");
61
61
  }
62
62
  let perpID = LiquidatorTool.symbolToPerpetualId(symbol, this.symbolToPerpStaticInfo);
63
- return yield this.proxyContract.isMaintenanceMarginSafe(perpID, traderAddr);
63
+ return yield this.proxyContract.isTraderMaintenanceMarginSafe(perpID, traderAddr);
64
64
  });
65
65
  }
66
66
  /**
@@ -79,5 +79,47 @@ class LiquidatorTool extends writeAccessHandler_1.default {
79
79
  return (0, d8XMath_1.ABK64x64ToFloat)(fAmount);
80
80
  });
81
81
  }
82
+ /**
83
+ * Total number of active accounts for this symbol, i.e. accounts with positions that are currently open.
84
+ * @param {string} symbol Symbol of the form ETH-USD-MATIC.
85
+ * @returns {number} Number of active accounts.
86
+ */
87
+ countActivePerpAccounts(symbol) {
88
+ return __awaiter(this, void 0, void 0, function* () {
89
+ if (this.proxyContract == null) {
90
+ throw Error("no proxy contract initialized. Use createProxyInstance().");
91
+ }
92
+ let perpID = LiquidatorTool.symbolToPerpetualId(symbol, this.symbolToPerpStaticInfo);
93
+ return yield this.proxyContract.countActivePerpAccounts(perpID);
94
+ });
95
+ }
96
+ /**
97
+ * Get addresses of active accounts by chunks.
98
+ * @param {string} symbol Symbol of the form ETH-USD-MATIC.
99
+ * @param {number} from From which account we start counting (0-indexed).
100
+ * @param {number} to Until which account we count, non inclusive.
101
+ * @returns {string[]} Array of addresses at locations 'from', 'from'+1 ,..., 'to'-1.
102
+ */
103
+ getActiveAccountsByChunks(symbol, from, to) {
104
+ return __awaiter(this, void 0, void 0, function* () {
105
+ if (this.proxyContract == null) {
106
+ throw Error("no proxy contract initialized. Use createProxyInstance().");
107
+ }
108
+ let perpID = LiquidatorTool.symbolToPerpetualId(symbol, this.symbolToPerpStaticInfo);
109
+ return yield this.proxyContract.getActivePerpAccountsByChunks(perpID, from, to);
110
+ });
111
+ }
112
+ /**
113
+ * Addresses for all the active accounts in this perpetual symbol.
114
+ * @param {string} symbol Symbol of the form ETH-USD-MATIC.
115
+ * @returns {string[]} Array of addresses.
116
+ */
117
+ getAllActiveAccounts(symbol) {
118
+ return __awaiter(this, void 0, void 0, function* () {
119
+ // checks are done inside the intermediate functions
120
+ let totalAccounts = yield this.countActivePerpAccounts(symbol);
121
+ return yield this.getActiveAccountsByChunks(symbol, 0, totalAccounts);
122
+ });
123
+ }
82
124
  }
83
125
  exports.default = LiquidatorTool;
@@ -31,6 +31,13 @@ export default class MarketData extends PerpetualDataHandler {
31
31
  * @returns {MarginAccount}
32
32
  */
33
33
  positionRisk(traderAddr: string, symbol: string): Promise<MarginAccount>;
34
+ /**
35
+ * Uses the Oracle(s) in the exchange to get the latest price of a given index in a given currency, if a route exists.
36
+ * @param {string} base Index name, e.g. ETH.
37
+ * @param {string} quote Quote currency, e.g. USD.
38
+ * @returns {number} Price of index in given currency.
39
+ */
40
+ getOraclePrice(base: string, quote: string): Promise<number | undefined>;
34
41
  /**
35
42
  * Query smart contract to get user orders and convert to user friendly order format.
36
43
  * @param {string} traderAddr Address of trader.
@@ -75,6 +75,21 @@ class MarketData extends perpetualDataHandler_1.default {
75
75
  return mgnAcct;
76
76
  });
77
77
  }
78
+ /**
79
+ * Uses the Oracle(s) in the exchange to get the latest price of a given index in a given currency, if a route exists.
80
+ * @param {string} base Index name, e.g. ETH.
81
+ * @param {string} quote Quote currency, e.g. USD.
82
+ * @returns {number} Price of index in given currency.
83
+ */
84
+ getOraclePrice(base, quote) {
85
+ return __awaiter(this, void 0, void 0, function* () {
86
+ if (this.proxyContract == null) {
87
+ throw Error("no proxy contract initialized. Use createProxyInstance().");
88
+ }
89
+ let px = yield this.proxyContract.getOraclePrice([(0, utils_1.toBytes4)(base), (0, utils_1.toBytes4)(quote)]);
90
+ return px == undefined ? undefined : (0, d8XMath_1.ABK64x64ToFloat)(px);
91
+ });
92
+ }
78
93
  /**
79
94
  * Query smart contract to get user orders and convert to user friendly order format.
80
95
  * @param {string} traderAddr Address of trader.
@@ -20,12 +20,24 @@ export default class OrderReferrerTool extends WriteAccessHandler {
20
20
  * @returns Transaction object.
21
21
  */
22
22
  executeOrder(symbol: string, orderId: string, referrerAddr?: string): Promise<ethers.providers.TransactionResponse>;
23
+ /**
24
+ * All the orders in the order book for a given symbol that are currently open.
25
+ * @param {string} symbol Symbol of the form ETH-USD-MATIC.
26
+ * @returns Array with all open orders and their IDs.
27
+ */
28
+ getAllOpenOrders(symbol: string): Promise<[Order[], string[]]>;
29
+ /**
30
+ * Total number of limit orders for this symbol, excluding those that have been cancelled/removed.
31
+ * @param {string} symbol Symbol of the form ETH-USD-MATIC.
32
+ * @returns {number} Number of open orders.
33
+ */
34
+ numberOfOpenOrders(symbol: string): Promise<number>;
23
35
  /**
24
36
  * Get a list of active conditional orders in the order book.
25
37
  * This a read-only action and does not incur in gas costs.
26
38
  * @param {string} symbol Symbol of the form ETH-USD-MATIC.
27
39
  * @param {number} numElements Maximum number of orders to poll.
28
- * @param {string} startAfter Optional order ID from where to start polling. Defaults to the first order.
40
+ * @param {string=} startAfter Optional order ID from where to start polling. Defaults to the first order.
29
41
  * @returns Array of orders and corresponding order IDs
30
42
  */
31
43
  pollLimitOrders(symbol: string, numElements: number, startAfter?: string): Promise<[Order[], string[]]>;
@@ -14,6 +14,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  const writeAccessHandler_1 = __importDefault(require("./writeAccessHandler"));
16
16
  const nodeSDKTypes_1 = require("./nodeSDKTypes");
17
+ const ethers_1 = require("ethers");
17
18
  /**
18
19
  * Methods to execute existing orders from the limit order book.
19
20
  */
@@ -46,12 +47,37 @@ class OrderReferrerTool extends writeAccessHandler_1.default {
46
47
  return yield orderBookSC.executeLimitOrderByDigest(orderId, referrerAddr);
47
48
  });
48
49
  }
50
+ /**
51
+ * All the orders in the order book for a given symbol that are currently open.
52
+ * @param {string} symbol Symbol of the form ETH-USD-MATIC.
53
+ * @returns Array with all open orders and their IDs.
54
+ */
55
+ getAllOpenOrders(symbol) {
56
+ return __awaiter(this, void 0, void 0, function* () {
57
+ let totalOrders = yield this.numberOfOpenOrders(symbol);
58
+ return yield this.pollLimitOrders(symbol, totalOrders);
59
+ });
60
+ }
61
+ /**
62
+ * Total number of limit orders for this symbol, excluding those that have been cancelled/removed.
63
+ * @param {string} symbol Symbol of the form ETH-USD-MATIC.
64
+ * @returns {number} Number of open orders.
65
+ */
66
+ numberOfOpenOrders(symbol) {
67
+ return __awaiter(this, void 0, void 0, function* () {
68
+ if (this.proxyContract == null) {
69
+ throw Error("no proxy contract initialized. Use createProxyInstance().");
70
+ }
71
+ const orderBookSC = this.getOrderBookContract(symbol);
72
+ return yield orderBookSC.numberOfOrderBookDigests();
73
+ });
74
+ }
49
75
  /**
50
76
  * Get a list of active conditional orders in the order book.
51
77
  * This a read-only action and does not incur in gas costs.
52
78
  * @param {string} symbol Symbol of the form ETH-USD-MATIC.
53
79
  * @param {number} numElements Maximum number of orders to poll.
54
- * @param {string} startAfter Optional order ID from where to start polling. Defaults to the first order.
80
+ * @param {string=} startAfter Optional order ID from where to start polling. Defaults to the first order.
55
81
  * @returns Array of orders and corresponding order IDs
56
82
  */
57
83
  pollLimitOrders(symbol, numElements, startAfter) {
@@ -60,7 +86,7 @@ class OrderReferrerTool extends writeAccessHandler_1.default {
60
86
  throw Error("no proxy contract initialized. Use createProxyInstance().");
61
87
  }
62
88
  if (typeof startAfter == "undefined") {
63
- startAfter = nodeSDKTypes_1.ZERO_ADDRESS;
89
+ startAfter = ethers_1.ethers.constants.HashZero;
64
90
  }
65
91
  const orderBookSC = this.getOrderBookContract(symbol);
66
92
  let [orders, orderIds] = yield orderBookSC.pollLimitOrders(startAfter, numElements);
@@ -310,16 +310,20 @@ class PerpetualDataHandler {
310
310
  // concatenate and find perpetual Id in map
311
311
  return symbols[0] + "-" + symbols[1] + "-" + symbols[2];
312
312
  }
313
- static _getByValue(map, searchValue) {
313
+ static _getByValue(map, searchValue, valueField) {
314
314
  for (let [key, value] of map.entries()) {
315
- if (value === searchValue) {
315
+ if (value[valueField] === searchValue) {
316
316
  return key;
317
317
  }
318
318
  }
319
+ return undefined;
319
320
  }
320
321
  static fromSmartContractOrder(order, symbolToPerpInfoMap) {
321
322
  // find symbol of perpetual id
322
- let symbol = PerpetualDataHandler._getByValue(symbolToPerpInfoMap, order.iPerpetualId);
323
+ let symbol = PerpetualDataHandler._getByValue(symbolToPerpInfoMap, order.iPerpetualId, "id");
324
+ if (symbol == undefined) {
325
+ throw Error(`Perpetual id ${order.iPerpetualId} not found. Check with marketData.exchangeInfo().`);
326
+ }
323
327
  let side = order.fAmount > 0 ? nodeSDKTypes_1.BUY_SIDE : nodeSDKTypes_1.SELL_SIDE;
324
328
  let limitPrice, stopPrice;
325
329
  let fLimitPrice = ethers_1.BigNumber.from(order.fLimitPrice);
@@ -344,9 +348,9 @@ class PerpetualDataHandler {
344
348
  reduceOnly: (0, utils_1.containsFlag)(ethers_1.BigNumber.from(order.flags), nodeSDKTypes_1.MASK_CLOSE_ONLY),
345
349
  limitPrice: limitPrice,
346
350
  keepPositionLvg: (0, utils_1.containsFlag)(ethers_1.BigNumber.from(order.flags), nodeSDKTypes_1.MASK_KEEP_POS_LEVERAGE),
347
- brokerFeeTbps: Number(order.brokerFeeTbps),
348
- brokerAddr: order.brokerAddr,
349
- brokerSignature: order.brokerSignature,
351
+ brokerFeeTbps: order.brokerFeeTbps == 0 ? undefined : Number(order.brokerFeeTbps),
352
+ brokerAddr: order.brokerAddr == nodeSDKTypes_1.ZERO_ADDRESS ? undefined : order.brokerAddr,
353
+ brokerSignature: order.brokerSignature == "0x" ? undefined : order.brokerSignature,
350
354
  stopPrice: stopPrice,
351
355
  leverage: (0, d8XMath_1.ABK64x64ToFloat)(ethers_1.BigNumber.from(order.fLeverage)),
352
356
  deadline: Number(order.iDeadline),
package/package.json CHANGED
@@ -12,7 +12,7 @@
12
12
  },
13
13
  "scripts": {
14
14
  "build": "tsc",
15
- "build:doc": "jsdoc2md --files ./src/accountTrade.ts --configure ./jsdoc2md.json > ./doc/accountTrade.md && jsdoc2md --files ./src/marketData.ts --configure ./jsdoc2md.json > ./doc/marketData.md && jsdoc2md --files ./src/liquidatorTool.ts --configure ./jsdoc2md.json > ./doc/liquidatorTool.md && jsdoc2md --files ./src/liquidityProviderTool.ts --configure ./jsdoc2md.json > ./doc/liquidityProviderTool.md && jsdoc2md --files ./src/brokerTool.ts --configure ./jsdoc2md.json > ./doc/brokerTool.md && jsdoc2md --files ./src/orderReferrerTool.ts --configure ./jsdoc2md.json > ./doc/orderReferrerTool.md",
15
+ "build:doc": "jsdoc2md --files ./src/accountTrade.ts --configure ./jsdoc2md.json > ./doc/accountTrade.md && jsdoc2md --files ./src/marketData.ts --configure ./jsdoc2md.json > ./doc/marketData.md && jsdoc2md --files ./src/liquidatorTool.ts --configure ./jsdoc2md.json > ./doc/liquidatorTool.md && jsdoc2md --files ./src/liquidityProviderTool.ts --configure ./jsdoc2md.json > ./doc/liquidityProviderTool.md && jsdoc2md --files ./src/brokerTool.ts --configure ./jsdoc2md.json > ./doc/brokerTool.md && jsdoc2md --files ./src/orderReferrerTool.ts --configure ./jsdoc2md.json > ./doc/orderReferrerTool.md && jsdoc2md --files ./src/*.ts --configure ./jsdoc2md.json > ./doc/d8x-perpetuals-sdk.md",
16
16
  "test": "jest",
17
17
  "coverage": "nyc -r lcov -e .ts -x \"*.test.ts\" npm run test"
18
18
  },
@@ -27,7 +27,7 @@
27
27
  },
28
28
  "name": "@d8x/perpetuals-sdk",
29
29
  "description": "Node TypeScript SDK for D8X Perpetual Futures",
30
- "version": "0.0.2",
30
+ "version": "0.0.3",
31
31
  "main": "./dist/index.js",
32
32
  "types": "./dist/index.d.ts",
33
33
  "directories": {
@@ -1,4 +1,5 @@
1
1
  import { ethers } from "ethers";
2
+ import { ABK64x64ToFloat } from "./d8XMath";
2
3
  import {
3
4
  NodeSDKConfig,
4
5
  Order,
@@ -91,6 +92,21 @@ export default class AccountTrade extends WriteAccessHandler {
91
92
  return feeTbps / 100_000;
92
93
  }
93
94
 
95
+ /**
96
+ * Exponentially weighted EMA of the total trading volume of all trades performed by this trader.
97
+ * The weights are chosen so that in average this coincides with the 30 day volume.
98
+ * @param {string} poolSymbolName Pool symbol name (e.g. MATIC, USDC, etc).
99
+ * @returns {number} Current trading volume for this trader, in USD.
100
+ */
101
+ public async getCurrentTraderVolume(poolSymbolName: string): Promise<number> {
102
+ if (this.proxyContract == null || this.signer == null) {
103
+ throw Error("no proxy contract or wallet initialized. Use createProxyInstance().");
104
+ }
105
+ let poolId = WriteAccessHandler._getPoolIdFromSymbol(poolSymbolName, this.poolStaticInfos);
106
+ let volume = await this.proxyContract.getCurrentTraderVolume(poolId, this.traderAddr);
107
+ return ABK64x64ToFloat(volume);
108
+ }
109
+
94
110
  /**
95
111
  * Static order function
96
112
  * @param order order type (not SmartContractOrder but Order)
package/src/brokerTool.ts CHANGED
@@ -17,62 +17,21 @@ export default class BrokerTool extends WriteAccessHandler {
17
17
  super(config, privateKey);
18
18
  }
19
19
 
20
- public async getBrokerInducedFee(poolSymbolName: string) {
21
- if (this.proxyContract == null || this.signer == null) {
22
- throw Error("no proxy contract or wallet initialized. Use createProxyInstance().");
23
- }
24
- let poolId = PerpetualDataHandler._getPoolIdFromSymbol(poolSymbolName, this.poolStaticInfos);
25
- let feeTbps = await this.proxyContract.getBrokerInducedFee(poolId, this.traderAddr);
26
- return feeTbps / 100_000;
27
- }
28
-
29
- /**
30
- * Total amount of collateral currency a broker has to deposit into the default fund to purchase one lot.
31
- * This is equivalent to the price of a lot expressed in a given pool's currency (e.g. MATIC, USDC, etc).
32
- * @param {string} poolSymbolName Pool symbol name (e.g. MATIC, USDC, etc).
33
- * @returns Broker lot size in a given pool's currency, e.g. in MATIC for poolSymbolName MATIC.
34
- */
35
- public async getLotSize(poolSymbolName: string): Promise<number> {
36
- if (this.proxyContract == null) {
37
- throw Error("no proxy contract initialized. Use createProxyInstance().");
38
- }
39
- let poolId = PerpetualDataHandler._getPoolIdFromSymbol(poolSymbolName, this.poolStaticInfos);
40
- let pool = await this.proxyContract.getLiquidityPool(poolId);
41
- let lot = ABK64x64ToFloat(pool.fBrokerCollateralLotSize);
42
- return lot;
43
- }
44
-
45
- /**
46
- * Provides information on how many lots a broker purchased for a given pool.
47
- * This is relevant to determine the broker's fee tier.
48
- * @param {string} poolSymbolName Pool symbol name (e.g. MATIC, USDC, etc).
49
- * @returns Number of lots purchased by this broker.
50
- */
51
- public async getBrokerDesignation(poolSymbolName: string): Promise<number> {
52
- if (this.proxyContract == null || this.signer == null) {
53
- throw Error("no proxy contract or wallet initialized. Use createProxyInstance().");
54
- }
55
- let poolId = PerpetualDataHandler._getPoolIdFromSymbol(poolSymbolName, this.poolStaticInfos);
56
- let designation = await this.proxyContract.getBrokerDesignation(poolId, this.traderAddr);
57
- return designation;
58
- }
20
+ // Fee getters
59
21
 
60
22
  /**
61
- * Deposit lots to the default fund of a given pool.
23
+ * Determine the exchange fee based on lots, traded volume, and D8X balance of this broker.
24
+ * This is the final exchange fee paid by the broker.
62
25
  * @param {string} poolSymbolName Pool symbol name (e.g. MATIC, USDC, etc).
63
- * @param lots Number of lots to deposit into this pool.
64
- * @returns Transaction object.
26
+ * @returns {number} Exchange fee for this broker, in decimals (i.e. 0.1% is 0.001)
65
27
  */
66
- public async brokerDepositToDefaultFund(
67
- poolSymbolName: string,
68
- lots: number
69
- ): Promise<ethers.providers.TransactionResponse> {
28
+ public async getBrokerInducedFee(poolSymbolName: string): Promise<number> {
70
29
  if (this.proxyContract == null || this.signer == null) {
71
30
  throw Error("no proxy contract or wallet initialized. Use createProxyInstance().");
72
31
  }
73
32
  let poolId = PerpetualDataHandler._getPoolIdFromSymbol(poolSymbolName, this.poolStaticInfos);
74
- let tx = await this.proxyContract.brokerDepositToDefaultFund(poolId, lots, { gasLimit: this.gasLimit });
75
- return tx;
33
+ let feeTbps = await this.proxyContract.getBrokerInducedFee(poolId, this.traderAddr);
34
+ return feeTbps / 100_000;
76
35
  }
77
36
 
78
37
  /**
@@ -80,8 +39,8 @@ export default class BrokerTool extends WriteAccessHandler {
80
39
  * The final exchange fee paid by the broker is equal to
81
40
  * maximum(brokerTool.getFeeForBrokerDesignation(poolSymbolName), brokerTool.getFeeForBrokerVolume(poolSymbolName), brokerTool.getFeeForBrokerStake())
82
41
  * @param {string} poolSymbolName Pool symbol name (e.g. MATIC, USDC, etc).
83
- * @param {number} lots Optional, designation to use if different from this broker's.
84
- * @returns Fee based solely on this broker's designation, in decimals (i.e. 0.1% is 0.001).
42
+ * @param {number=} lots Optional, designation to use if different from this broker's.
43
+ * @returns {number} Fee based solely on this broker's designation, in decimals (i.e. 0.1% is 0.001).
85
44
  */
86
45
  public async getFeeForBrokerDesignation(poolSymbolName: string, lots?: number): Promise<number> {
87
46
  if (this.proxyContract == null || this.signer == null) {
@@ -103,9 +62,9 @@ export default class BrokerTool extends WriteAccessHandler {
103
62
  * The final exchange fee paid by the broker is equal to
104
63
  * maximum(brokerTool.getFeeForBrokerDesignation(poolSymbolName), brokerTool.getFeeForBrokerVolume(poolSymbolName), brokerTool.getFeeForBrokerStake())
105
64
  * @param {string} poolSymbolName Pool symbol name (e.g. MATIC, USDC, etc).
106
- * @returns Fee based solely on a broker's traded volume in the corresponding pool, in decimals (i.e. 0.1% is 0.001).
65
+ * @returns {number} Fee based solely on a broker's traded volume in the corresponding pool, in decimals (i.e. 0.1% is 0.001).
107
66
  */
108
- public async getFeeForBrokerVolume(poolSymbolName: string): Promise<number | undefined> {
67
+ public async getFeeForBrokerVolume(poolSymbolName: string): Promise<number> {
109
68
  if (this.proxyContract == null || this.signer == null) {
110
69
  throw Error("no proxy contract or wallet initialized. Use createProxyInstance().");
111
70
  }
@@ -119,7 +78,7 @@ export default class BrokerTool extends WriteAccessHandler {
119
78
  * The final exchange fee paid by the broker is equal to
120
79
  * maximum(brokerTool.getFeeForBrokerDesignation(symbol, lots), brokerTool.getFeeForBrokerVolume(symbol), brokerTool.getFeeForBrokerStake)
121
80
  * @param {string=} brokerAddr Address of the broker in question, if different from the one calling this function.
122
- * @returns Fee based solely on a broker's D8X balance, in decimals (i.e. 0.1% is 0.001).
81
+ * @returns {number} Fee based solely on a broker's D8X balance, in decimals (i.e. 0.1% is 0.001).
123
82
  */
124
83
  public async getFeeForBrokerStake(brokerAddr?: string): Promise<number> {
125
84
  if (this.proxyContract == null || this.signer == null) {
@@ -138,9 +97,10 @@ export default class BrokerTool extends WriteAccessHandler {
138
97
  * and it takes into account whether the order given here has been signed by a broker or not.
139
98
  * Use this, for instance, to verify that the fee to be charged for a given order is as expected,
140
99
  * before and after signing it with brokerTool.signOrder.
100
+ * This fee is equal or lower than the broker induced fee, provided the order is properly signed.
141
101
  * @param {Order} order Order for which to determine the exchange fee. Not necessarily signed by this broker.
142
102
  * @param {string} traderAddr Address of the trader for whom to determine the fee.
143
- * @returns Fee in decimals (i.e. 0.1% is 0.001).
103
+ * @returns {number} Fee in decimals (i.e. 0.1% is 0.001).
144
104
  */
145
105
  public async determineExchangeFee(order: Order, traderAddr: string): Promise<number> {
146
106
  if (this.proxyContract == null || this.signer == null) {
@@ -151,13 +111,83 @@ export default class BrokerTool extends WriteAccessHandler {
151
111
  return feeTbps / 100_000;
152
112
  }
153
113
 
114
+ // Volume
115
+
116
+ /**
117
+ * Exponentially weighted EMA of the total trading volume of all trades performed under this broker.
118
+ * The weights are chosen so that in average this coincides with the 30 day volume.
119
+ * @param {string} poolSymbolName Pool symbol name (e.g. MATIC, USDC, etc).
120
+ * @returns {number} Current trading volume for this broker, in USD.
121
+ */
122
+ public async getCurrentBrokerVolume(poolSymbolName: string): Promise<number> {
123
+ if (this.proxyContract == null || this.signer == null) {
124
+ throw Error("no proxy contract or wallet initialized. Use createProxyInstance().");
125
+ }
126
+ let poolId = PerpetualDataHandler._getPoolIdFromSymbol(poolSymbolName, this.poolStaticInfos);
127
+ let volume = await this.proxyContract.getCurrentBrokerVolume(poolId, this.traderAddr);
128
+ return ABK64x64ToFloat(volume);
129
+ }
130
+
131
+ // Lots
132
+
133
+ /**
134
+ * Total amount of collateral currency a broker has to deposit into the default fund to purchase one lot.
135
+ * This is equivalent to the price of a lot expressed in a given pool's currency (e.g. MATIC, USDC, etc).
136
+ * @param {string} poolSymbolName Pool symbol name (e.g. MATIC, USDC, etc).
137
+ * @returns {number} Broker lot size in a given pool's currency, e.g. in MATIC for poolSymbolName MATIC.
138
+ */
139
+ public async getLotSize(poolSymbolName: string): Promise<number> {
140
+ if (this.proxyContract == null) {
141
+ throw Error("no proxy contract initialized. Use createProxyInstance().");
142
+ }
143
+ let poolId = PerpetualDataHandler._getPoolIdFromSymbol(poolSymbolName, this.poolStaticInfos);
144
+ let pool = await this.proxyContract.getLiquidityPool(poolId);
145
+ let lot = ABK64x64ToFloat(pool.fBrokerCollateralLotSize);
146
+ return lot;
147
+ }
148
+
149
+ /**
150
+ * Provides information on how many lots a broker purchased for a given pool.
151
+ * This is relevant to determine the broker's fee tier.
152
+ * @param {string} poolSymbolName Pool symbol name (e.g. MATIC, USDC, etc).
153
+ * @returns {number} Number of lots purchased by this broker.
154
+ */
155
+ public async getBrokerDesignation(poolSymbolName: string): Promise<number> {
156
+ if (this.proxyContract == null || this.signer == null) {
157
+ throw Error("no proxy contract or wallet initialized. Use createProxyInstance().");
158
+ }
159
+ let poolId = PerpetualDataHandler._getPoolIdFromSymbol(poolSymbolName, this.poolStaticInfos);
160
+ let designation = await this.proxyContract.getBrokerDesignation(poolId, this.traderAddr);
161
+ return designation;
162
+ }
163
+
164
+ /**
165
+ * Deposit lots to the default fund of a given pool.
166
+ * @param {string} poolSymbolName Pool symbol name (e.g. MATIC, USDC, etc).
167
+ * @param {number} lots Number of lots to deposit into this pool.
168
+ * @returns {ethers.providers.TransactionResponse} Transaction object.
169
+ */
170
+ public async brokerDepositToDefaultFund(
171
+ poolSymbolName: string,
172
+ lots: number
173
+ ): Promise<ethers.providers.TransactionResponse> {
174
+ if (this.proxyContract == null || this.signer == null) {
175
+ throw Error("no proxy contract or wallet initialized. Use createProxyInstance().");
176
+ }
177
+ let poolId = PerpetualDataHandler._getPoolIdFromSymbol(poolSymbolName, this.poolStaticInfos);
178
+ let tx = await this.proxyContract.brokerDepositToDefaultFund(poolId, lots, { gasLimit: this.gasLimit });
179
+ return tx;
180
+ }
181
+
182
+ // Signatures
183
+
154
184
  /**
155
185
  * Adds this broker's signature to an order so that it can be submitted by an approved trader.
156
186
  * @param {Order} order Order to sign.
157
187
  * @param {string} traderAddr Address of trader submitting the order.
158
188
  * @param {number} feeDecimals Fee that this broker is approving for the trader.
159
189
  * @param {number} deadline Deadline for the order to be executed.
160
- * @returns An order signed by this broker, which can be submitted directly with AccountTrade.order.
190
+ * @returns {Order} An order signed by this broker, which can be submitted directly with AccountTrade.order.
161
191
  */
162
192
  public async signOrder(order: Order, traderAddr: string, brokerFee: number, deadline: number): Promise<Order> {
163
193
  if (this.proxyContract == null || this.signer == null) {
@@ -186,7 +216,7 @@ export default class BrokerTool extends WriteAccessHandler {
186
216
  * @param {string} symbol Perpetual that this trader will be trading, of the form ETH-USD-MATIC.
187
217
  * @param {number} brokerFee Broker fee for this trader, in decimals (i.e. 0.1% is 0.001).
188
218
  * @param {number} deadline Deadline for the order to be executed.
189
- * @returns Broker signature approving this trader's fee, symbol, and deadline.
219
+ * @returns {string} Broker signature approving this trader's fee, symbol, and deadline.
190
220
  * @ignore
191
221
  */
192
222
  public async createSignatureForTrader(
@@ -250,11 +280,13 @@ export default class BrokerTool extends WriteAccessHandler {
250
280
  return await signer.signMessage(digestBuffer);
251
281
  }
252
282
 
283
+ // Transfer ownership
284
+
253
285
  /**
254
286
  * Transfer ownership of a broker's status to a new wallet.
255
- * @param poolSymbolName Symbol refers to the pool (e.g., MATIC for the MATIC-pool)
256
- * @param newAddress The address this broker wants to use from now on.
257
- * @returns ethers transaction object
287
+ * @param {string} poolSymbolName Pool symbol name (e.g. MATIC, USDC, etc).
288
+ * @param {string} newAddress The address this broker wants to use from now on.
289
+ * @returns {ethers.providers.TransactionResponse} ethers transaction object
258
290
  */
259
291
  public async transferOwnership(
260
292
  poolSymbolName: string,
@@ -47,7 +47,7 @@ export default class LiquidatorTool extends WriteAccessHandler {
47
47
  throw Error("no proxy contract initialized. Use createProxyInstance().");
48
48
  }
49
49
  let perpID = LiquidatorTool.symbolToPerpetualId(symbol, this.symbolToPerpStaticInfo);
50
- return await this.proxyContract.isMaintenanceMarginSafe(perpID, traderAddr);
50
+ return await this.proxyContract.isTraderMaintenanceMarginSafe(perpID, traderAddr);
51
51
  }
52
52
 
53
53
  /**
@@ -65,7 +65,42 @@ export default class LiquidatorTool extends WriteAccessHandler {
65
65
  return ABK64x64ToFloat(fAmount);
66
66
  }
67
67
 
68
- /*
69
- TODO
70
- */
68
+ /**
69
+ * Total number of active accounts for this symbol, i.e. accounts with positions that are currently open.
70
+ * @param {string} symbol Symbol of the form ETH-USD-MATIC.
71
+ * @returns {number} Number of active accounts.
72
+ */
73
+ public async countActivePerpAccounts(symbol: string): Promise<number> {
74
+ if (this.proxyContract == null) {
75
+ throw Error("no proxy contract initialized. Use createProxyInstance().");
76
+ }
77
+ let perpID = LiquidatorTool.symbolToPerpetualId(symbol, this.symbolToPerpStaticInfo);
78
+ return await this.proxyContract.countActivePerpAccounts(perpID);
79
+ }
80
+
81
+ /**
82
+ * Get addresses of active accounts by chunks.
83
+ * @param {string} symbol Symbol of the form ETH-USD-MATIC.
84
+ * @param {number} from From which account we start counting (0-indexed).
85
+ * @param {number} to Until which account we count, non inclusive.
86
+ * @returns {string[]} Array of addresses at locations 'from', 'from'+1 ,..., 'to'-1.
87
+ */
88
+ public async getActiveAccountsByChunks(symbol: string, from: number, to: number): Promise<string[]> {
89
+ if (this.proxyContract == null) {
90
+ throw Error("no proxy contract initialized. Use createProxyInstance().");
91
+ }
92
+ let perpID = LiquidatorTool.symbolToPerpetualId(symbol, this.symbolToPerpStaticInfo);
93
+ return await this.proxyContract.getActivePerpAccountsByChunks(perpID, from, to);
94
+ }
95
+
96
+ /**
97
+ * Addresses for all the active accounts in this perpetual symbol.
98
+ * @param {string} symbol Symbol of the form ETH-USD-MATIC.
99
+ * @returns {string[]} Array of addresses.
100
+ */
101
+ public async getAllActiveAccounts(symbol: string): Promise<string[]> {
102
+ // checks are done inside the intermediate functions
103
+ let totalAccounts = await this.countActivePerpAccounts(symbol);
104
+ return await this.getActiveAccountsByChunks(symbol, 0, totalAccounts);
105
+ }
71
106
  }
package/src/marketData.ts CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  } from "./nodeSDKTypes";
12
12
  import { BigNumber, BytesLike, ethers } from "ethers";
13
13
  import { floatToABK64x64, ABK64x64ToFloat } from "./d8XMath";
14
- import { fromBytes4HexString } from "./utils";
14
+ import { fromBytes4HexString, toBytes4 } from "./utils";
15
15
  import PerpetualDataHandler from "./perpetualDataHandler";
16
16
  import { SmartContractOrder, Order } from "./nodeSDKTypes";
17
17
 
@@ -75,6 +75,20 @@ export default class MarketData extends PerpetualDataHandler {
75
75
  return mgnAcct;
76
76
  }
77
77
 
78
+ /**
79
+ * Uses the Oracle(s) in the exchange to get the latest price of a given index in a given currency, if a route exists.
80
+ * @param {string} base Index name, e.g. ETH.
81
+ * @param {string} quote Quote currency, e.g. USD.
82
+ * @returns {number} Price of index in given currency.
83
+ */
84
+ public async getOraclePrice(base: string, quote: string): Promise<number | undefined> {
85
+ if (this.proxyContract == null) {
86
+ throw Error("no proxy contract initialized. Use createProxyInstance().");
87
+ }
88
+ let px = await this.proxyContract.getOraclePrice([toBytes4(base), toBytes4(quote)]);
89
+ return px == undefined ? undefined : ABK64x64ToFloat(px);
90
+ }
91
+
78
92
  /**
79
93
  * Query smart contract to get user orders and convert to user friendly order format.
80
94
  * @param {string} traderAddr Address of trader.
@@ -38,12 +38,35 @@ export default class OrderReferrerTool extends WriteAccessHandler {
38
38
  return await orderBookSC.executeLimitOrderByDigest(orderId, referrerAddr);
39
39
  }
40
40
 
41
+ /**
42
+ * All the orders in the order book for a given symbol that are currently open.
43
+ * @param {string} symbol Symbol of the form ETH-USD-MATIC.
44
+ * @returns Array with all open orders and their IDs.
45
+ */
46
+ public async getAllOpenOrders(symbol: string): Promise<[Order[], string[]]> {
47
+ let totalOrders = await this.numberOfOpenOrders(symbol);
48
+ return await this.pollLimitOrders(symbol, totalOrders);
49
+ }
50
+
51
+ /**
52
+ * Total number of limit orders for this symbol, excluding those that have been cancelled/removed.
53
+ * @param {string} symbol Symbol of the form ETH-USD-MATIC.
54
+ * @returns {number} Number of open orders.
55
+ */
56
+ public async numberOfOpenOrders(symbol: string): Promise<number> {
57
+ if (this.proxyContract == null) {
58
+ throw Error("no proxy contract initialized. Use createProxyInstance().");
59
+ }
60
+ const orderBookSC = this.getOrderBookContract(symbol);
61
+ return await orderBookSC.numberOfOrderBookDigests();
62
+ }
63
+
41
64
  /**
42
65
  * Get a list of active conditional orders in the order book.
43
66
  * This a read-only action and does not incur in gas costs.
44
67
  * @param {string} symbol Symbol of the form ETH-USD-MATIC.
45
68
  * @param {number} numElements Maximum number of orders to poll.
46
- * @param {string} startAfter Optional order ID from where to start polling. Defaults to the first order.
69
+ * @param {string=} startAfter Optional order ID from where to start polling. Defaults to the first order.
47
70
  * @returns Array of orders and corresponding order IDs
48
71
  */
49
72
  public async pollLimitOrders(symbol: string, numElements: number, startAfter?: string): Promise<[Order[], string[]]> {
@@ -51,7 +74,7 @@ export default class OrderReferrerTool extends WriteAccessHandler {
51
74
  throw Error("no proxy contract initialized. Use createProxyInstance().");
52
75
  }
53
76
  if (typeof startAfter == "undefined") {
54
- startAfter = ZERO_ADDRESS;
77
+ startAfter = ethers.constants.HashZero;
55
78
  }
56
79
  const orderBookSC = this.getOrderBookContract(symbol);
57
80
  let [orders, orderIds] = await orderBookSC.pollLimitOrders(startAfter, numElements);
@@ -114,6 +137,7 @@ export default class OrderReferrerTool extends WriteAccessHandler {
114
137
  * - [x] executeLimitOrderByDigest
115
138
  * - [x] pollLimitOrders
116
139
  * - [x] isTradeable
140
+ * - [ ] get all limit orders
117
141
  * - [ ] tests
118
142
  */
119
143
  }
@@ -390,12 +390,13 @@ export default class PerpetualDataHandler {
390
390
  return symbols[0] + "-" + symbols[1] + "-" + symbols[2];
391
391
  }
392
392
 
393
- private static _getByValue(map: any, searchValue: any) {
393
+ private static _getByValue(map: any, searchValue: any, valueField: any) {
394
394
  for (let [key, value] of map.entries()) {
395
- if (value === searchValue) {
395
+ if (value[valueField] === searchValue) {
396
396
  return key;
397
397
  }
398
398
  }
399
+ return undefined;
399
400
  }
400
401
 
401
402
  protected static fromSmartContractOrder(
@@ -403,7 +404,10 @@ export default class PerpetualDataHandler {
403
404
  symbolToPerpInfoMap: Map<string, PerpetualStaticInfo>
404
405
  ): Order {
405
406
  // find symbol of perpetual id
406
- let symbol = PerpetualDataHandler._getByValue(symbolToPerpInfoMap, order.iPerpetualId);
407
+ let symbol = PerpetualDataHandler._getByValue(symbolToPerpInfoMap, order.iPerpetualId, "id");
408
+ if (symbol == undefined) {
409
+ throw Error(`Perpetual id ${order.iPerpetualId} not found. Check with marketData.exchangeInfo().`);
410
+ }
407
411
  let side = order.fAmount > 0 ? BUY_SIDE : SELL_SIDE;
408
412
  let limitPrice, stopPrice;
409
413
  let fLimitPrice: BigNumber | undefined = BigNumber.from(order.fLimitPrice);
@@ -419,16 +423,16 @@ export default class PerpetualDataHandler {
419
423
  stopPrice = ABK64x64ToFloat(fStopPrice);
420
424
  }
421
425
  let userOrder: Order = {
422
- symbol: symbol,
426
+ symbol: symbol!,
423
427
  side: side,
424
428
  type: PerpetualDataHandler._flagToOrderType(order),
425
429
  quantity: Math.abs(ABK64x64ToFloat(BigNumber.from(order.fAmount))),
426
430
  reduceOnly: containsFlag(BigNumber.from(order.flags), MASK_CLOSE_ONLY),
427
431
  limitPrice: limitPrice,
428
432
  keepPositionLvg: containsFlag(BigNumber.from(order.flags), MASK_KEEP_POS_LEVERAGE),
429
- brokerFeeTbps: Number(order.brokerFeeTbps),
430
- brokerAddr: order.brokerAddr,
431
- brokerSignature: order.brokerSignature,
433
+ brokerFeeTbps: order.brokerFeeTbps == 0 ? undefined : Number(order.brokerFeeTbps),
434
+ brokerAddr: order.brokerAddr == ZERO_ADDRESS ? undefined : order.brokerAddr,
435
+ brokerSignature: order.brokerSignature == "0x" ? undefined : order.brokerSignature,
432
436
  stopPrice: stopPrice,
433
437
  leverage: ABK64x64ToFloat(BigNumber.from(order.fLeverage)),
434
438
  deadline: Number(order.iDeadline),