@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
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const ethers_1 = require("ethers");
16
+ const perpetualDataHandler_1 = __importDefault(require("./perpetualDataHandler"));
17
+ const nodeSDKTypes_1 = require("./nodeSDKTypes");
18
+ const utils_1 = require("./utils");
19
+ const d8XMath_1 = require("./d8XMath");
20
+ /**
21
+ * This is a parent class for the classes that require
22
+ * write access to the contracts.
23
+ * This class requires a private key and executes smart-contract interaction that
24
+ * require gas-payments.
25
+ */
26
+ class WriteAccessHandler extends perpetualDataHandler_1.default {
27
+ /**
28
+ * Constructor
29
+ * @param config configuration
30
+ * @param privateKey private key of account that trades
31
+ */
32
+ constructor(config, privateKey) {
33
+ super(config);
34
+ this.traderAddr = "";
35
+ this.signer = null;
36
+ this.gasLimit = 15000000;
37
+ this.chainId = 0;
38
+ this.privateKey = privateKey;
39
+ if (config.gasLimit != undefined) {
40
+ this.gasLimit = config.gasLimit;
41
+ }
42
+ }
43
+ /**
44
+ * Initialize the AccountTrade-Class with this function
45
+ * to create instance of D8X perpetual contract and gather information
46
+ * about perpetual currencies
47
+ */
48
+ createProxyInstance() {
49
+ return __awaiter(this, void 0, void 0, function* () {
50
+ this.provider = new ethers_1.ethers.providers.JsonRpcProvider(this.nodeURL);
51
+ const wallet = new ethers_1.ethers.Wallet(this.privateKey);
52
+ this.signer = wallet.connect(this.provider);
53
+ yield this.initContractsAndData(this.signer);
54
+ this.traderAddr = wallet.address;
55
+ this.chainId = (yield this.provider.getNetwork()).chainId;
56
+ });
57
+ }
58
+ /**
59
+ * Set allowance for ar margin token (e.g., MATIC, ETH, USDC)
60
+ * @param symbol token in 'long-form' such as MATIC, symbol also fine (ETH-USD-MATIC)
61
+ * @param amount optional, amount to approve if not 'infinity'
62
+ * @returns transaction hash
63
+ */
64
+ setAllowance(symbol, amount = undefined) {
65
+ return __awaiter(this, void 0, void 0, function* () {
66
+ //extract margin-currency name
67
+ let symbolarr = symbol.split("-");
68
+ symbol = symbol.length == 3 ? symbolarr[2] : symbolarr[0];
69
+ //transform into bytes4 currencies (without the space): "BTC", "USD", "MATC"
70
+ symbol = (0, utils_1.to4Chars)(symbol);
71
+ symbol = symbol.replace(/\0/g, "");
72
+ let marginTokenAddr = this.symbolToTokenAddrMap.get(symbol);
73
+ if (marginTokenAddr == undefined || this.signer == null) {
74
+ throw Error("No margin token or signer defined, call createProxyInstance");
75
+ }
76
+ let amountDec18;
77
+ if (amount == undefined) {
78
+ amountDec18 = nodeSDKTypes_1.MAX_UINT_256;
79
+ }
80
+ else {
81
+ amountDec18 = (0, d8XMath_1.floatToDec18)(amount);
82
+ }
83
+ return WriteAccessHandler._setAllowance(marginTokenAddr, this.proxyAddr, this.signer, amountDec18);
84
+ });
85
+ }
86
+ static _setAllowance(tokenAddr, proxyAddr, signer, amount) {
87
+ return __awaiter(this, void 0, void 0, function* () {
88
+ const marginToken = new ethers_1.ethers.Contract(tokenAddr, nodeSDKTypes_1.ERC20_ABI, signer);
89
+ let tx = yield marginToken.approve(proxyAddr, amount);
90
+ yield tx.wait();
91
+ return tx.hash;
92
+ });
93
+ }
94
+ }
95
+ exports.default = WriteAccessHandler;
package/module.d.ts ADDED
@@ -0,0 +1 @@
1
+ declare module "@d8x/perpetuals-sdk";
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "dependencies": {
3
+ "@babel/core": "^7.20.2",
4
+ "@types/jest": "^29.2.3",
5
+ "@types/node": "^18.11.9",
6
+ "babel-jest": "^29.3.1",
7
+ "ethers": "^5.7.2",
8
+ "jest": "^29.3.1",
9
+ "ts-jest": "^29.0.3",
10
+ "ts-node": "^10.9.1",
11
+ "typescript": "^4.9.3"
12
+ },
13
+ "scripts": {
14
+ "build": "tsc",
15
+ "build:doc": "jsdoc2md --files ./src/accountTrade.ts --configure ./jsdoc2md.json > ./doc/accountTrade.md",
16
+ "test": "jest",
17
+ "coverage": "nyc -r lcov -e .ts -x \"*.test.ts\" npm run test"
18
+ },
19
+ "devDependencies": {
20
+ "@babel/plugin-proposal-class-properties": "^7.18.6",
21
+ "@babel/plugin-proposal-object-rest-spread": "^7.20.2",
22
+ "@babel/preset-env": "^7.20.2",
23
+ "@babel/preset-typescript": "^7.18.6",
24
+ "jsdoc-babel": "^0.5.0",
25
+ "jsdoc-to-markdown": "^7.1.1",
26
+ "json2md": "^2.0.0"
27
+ },
28
+ "name": "@d8x/perpetuals-sdk",
29
+ "description": "Node TypeScript SDK for D8X Perpetual Futures",
30
+ "version": "0.0.1",
31
+ "main": "./dist/index.js",
32
+ "types": "./dist/index.d.ts",
33
+ "directories": {
34
+ "test": "test"
35
+ },
36
+ "files": [
37
+ "module.d.ts",
38
+ "src/*.ts",
39
+ "src/*.json",
40
+ "src/*.md",
41
+ "dist/*.ts",
42
+ "dist/*.js",
43
+ "abi/*.json",
44
+ "config/*.json"
45
+ ],
46
+ "repository": {
47
+ "type": "git",
48
+ "url": "git+https://github.com/D8-X/d8x-futures-node-sdk.git"
49
+ },
50
+ "keywords": [
51
+ "d8x",
52
+ "perpetuals",
53
+ "node",
54
+ "sdk",
55
+ "api"
56
+ ],
57
+ "author": "d8x",
58
+ "license": "UNLICENSED",
59
+ "bugs": {
60
+ "url": "https://github.com/D8-X/d8x-futures-node-sdk/issues"
61
+ },
62
+ "homepage": "https://github.com/D8-X/d8x-futures-node-sdk#readme"
63
+ }
@@ -0,0 +1,217 @@
1
+ import { BigNumber, BigNumberish, ethers, Wallet } from "ethers";
2
+ import {
3
+ BUY_SIDE,
4
+ NodeSDKConfig,
5
+ Order,
6
+ SmartContractOrder,
7
+ SELL_SIDE,
8
+ ZERO_ADDRESS,
9
+ MAX_64x64,
10
+ MAX_UINT_256,
11
+ ORDER_MAX_DURATION_SEC,
12
+ ORDER_TYPE_LIMIT,
13
+ ORDER_TYPE_MARKET,
14
+ ORDER_TYPE_STOP_MARKET,
15
+ ORDER_TYPE_STOP_LIMIT,
16
+ MASK_CLOSE_ONLY,
17
+ MASK_LIMIT_ORDER,
18
+ MASK_MARKET_ORDER,
19
+ MASK_STOP_ORDER,
20
+ MASK_KEEP_POS_LEVERAGE,
21
+ COLLATERAL_CURRENCY_BASE,
22
+ COLLATERAL_CURRENCY_QUOTE,
23
+ ERC20_ABI,
24
+ PerpetualStaticInfo,
25
+ } from "./nodeSDKTypes";
26
+ import { floatToABK64x64, ABK64x64ToFloat, dec18ToFloat } from "./d8XMath";
27
+ import { combineFlags, to4Chars } from "./utils";
28
+ import WriteAccessHandler from "./writeAccessHandler";
29
+ //import { abi, rawEncode } from "ethereumjs-abi";
30
+
31
+ /**
32
+ * Account and Trade.
33
+ * This class requires a private key and executes smart-contract interaction that
34
+ * require gas-payments.
35
+ */
36
+ export default class AccountTrade extends WriteAccessHandler {
37
+ /**
38
+ * Constructor
39
+ * @param {NodeSDKConfig} config Configuration object, see PerpetualDataHandler.readSDKConfig.
40
+ * @param {string} privateKey Private key of account that trades.
41
+ */
42
+ public constructor(config: NodeSDKConfig, privateKey: string) {
43
+ super(config, privateKey);
44
+ }
45
+
46
+ /**
47
+ * Cancels an existing order on the exchange.
48
+ * @param {string} symbol Symbol of the form ETH-USD-MATIC.
49
+ * @param {string} orderId ID of the order to be cancelled.
50
+ */
51
+ public async cancelOrder(symbol: string, orderId: string): Promise<string | undefined> {
52
+ if (this.proxyContract == null || this.signer == null) {
53
+ throw Error("no proxy contract or wallet initialized. Use createProxyInstance().");
54
+ }
55
+ let orderBookContract: ethers.Contract | null = null;
56
+ orderBookContract = this.getOrderBookContract(symbol);
57
+
58
+ return await this._cancelOrder(symbol, orderId, orderBookContract);
59
+ }
60
+
61
+ /*
62
+ TODO: -deposit (margin into account)
63
+ -withdraw margin withdraw(uint24 _iPerpetualId, int128 _fAmount)
64
+
65
+ */
66
+
67
+ /**
68
+ * Submits an order to the exchange.
69
+ * @param {Order} order Order struct.
70
+ * @returns {string} Transaction hash.
71
+ */
72
+ public async order(order: Order): Promise<string | undefined> {
73
+ if (this.proxyContract == null || this.signer == null) {
74
+ throw Error("no proxy contract or wallet initialized. Use createProxyInstance().");
75
+ }
76
+ let orderBookContract: ethers.Contract | null = null;
77
+ if (order.type != ORDER_TYPE_MARKET) {
78
+ orderBookContract = this.getOrderBookContract(order.symbol);
79
+ }
80
+ return await this._order(
81
+ order,
82
+ this.traderAddr,
83
+ this.symbolToPerpStaticInfo,
84
+ this.proxyContract,
85
+ orderBookContract,
86
+ this.chainId,
87
+ this.signer,
88
+ this.gasLimit
89
+ );
90
+ }
91
+
92
+ /**
93
+ * Static order function
94
+ * @param order order type (not SmartContractOrder but Order)
95
+ * @param traderAddr trader address
96
+ * @param symbolToPerpetualMap maps the symbol (MATIC-USD-MATIC)-type format to the perpetual id
97
+ * @param proxyContract contract instance of D8X perpetuals
98
+ * @param orderBookContract order book contract or null
99
+ * @param chainId chain Id of network
100
+ * @param signer instance of ethers wallet that can write
101
+ * @param gasLimit gas limit to be used for the trade
102
+ * @returns transaction hash
103
+ * @ignore
104
+ */
105
+ public async _order(
106
+ order: Order,
107
+ traderAddr: string,
108
+ symbolToPerpetualMap: Map<string, PerpetualStaticInfo>,
109
+ proxyContract: ethers.Contract,
110
+ orderBookContract: ethers.Contract | null,
111
+ chainId: number,
112
+ signer: ethers.Wallet,
113
+ gasLimit: number
114
+ ): Promise<string | undefined> {
115
+ let scOrder = AccountTrade.toSmartContractOrder(order, traderAddr, symbolToPerpetualMap);
116
+ // if we are here, we have a clean order
117
+ // decide whether to send order to Limit Order Book or AMM based on order type
118
+ let tx: ethers.Transaction;
119
+ if (order.type == ORDER_TYPE_MARKET) {
120
+ // send market order
121
+ tx = await proxyContract.trade(scOrder, { gasLimit: gasLimit });
122
+ } else {
123
+ // conditional order so the order is sent to the order-book
124
+ if (orderBookContract == null) {
125
+ throw Error("Order book contract not provided.");
126
+ }
127
+ let signature = await this._createSignature(scOrder, chainId, true, signer, proxyContract.address);
128
+ tx = await orderBookContract.createLimitOrder(scOrder, signature, { gasLimit: gasLimit });
129
+ }
130
+ return tx.hash;
131
+ }
132
+
133
+ protected async _cancelOrder(
134
+ symbol: string,
135
+ orderId: string,
136
+ orderBookContract: ethers.Contract | null
137
+ ): Promise<string | undefined> {
138
+ if (orderBookContract == null || this.signer == null) {
139
+ throw Error(`Order Book contract for symbol ${symbol} or signer not defined`);
140
+ }
141
+ let scOrder: SmartContractOrder = await orderBookContract.orderOfDigest(orderId);
142
+ let signature = await this._createSignature(scOrder, this.chainId, false, this.signer, this.proxyAddr);
143
+ return await orderBookContract.cancelLimitOrder(orderId, signature);
144
+ }
145
+
146
+ /**
147
+ * Creates a signature
148
+ * @param order smart-contract-type order
149
+ * @param chainId chainId of network
150
+ * @param isNewOrder true unless we cancel
151
+ * @param signer ethereum-type wallet
152
+ * @param proxyAddress address of the contract
153
+ * @returns signature as string
154
+ * @ignore
155
+ */
156
+ private async _createSignature(
157
+ order: SmartContractOrder,
158
+ chainId: number,
159
+ isNewOrder: boolean,
160
+ signer: ethers.Wallet,
161
+ proxyAddress: string
162
+ ): Promise<String> {
163
+ const NAME = "Perpetual Trade Manager";
164
+ const DOMAIN_TYPEHASH = ethers.utils.keccak256(
165
+ Buffer.from("EIP712Domain(string name,uint256 chainId,address verifyingContract)")
166
+ );
167
+ let abiCoder = ethers.utils.defaultAbiCoder;
168
+ let domainSeparator = ethers.utils.keccak256(
169
+ abiCoder.encode(
170
+ ["bytes32", "bytes32", "uint256", "address"],
171
+ [DOMAIN_TYPEHASH, ethers.utils.keccak256(Buffer.from(NAME)), chainId, proxyAddress]
172
+ )
173
+ );
174
+ const TRADE_ORDER_TYPEHASH = ethers.utils.keccak256(
175
+ Buffer.from(
176
+ "Order(uint24 iPerpetualId,uint16 brokerFeeTbps,address traderAddr,address brokerAddr,int128 fAmount,int128 fLimitPrice,int128 fTriggerPrice,uint256 iDeadline,uint32 flags,int128 fLeverage,uint256 createdTimestamp)"
177
+ )
178
+ );
179
+ let structHash = ethers.utils.keccak256(
180
+ abiCoder.encode(
181
+ [
182
+ "bytes32",
183
+ "uint24",
184
+ "uint16",
185
+ "address",
186
+ "address",
187
+ "int128",
188
+ "int128",
189
+ "int128",
190
+ "uint256",
191
+ "uint32",
192
+ "int128",
193
+ "uint256",
194
+ ],
195
+ [
196
+ TRADE_ORDER_TYPEHASH,
197
+ order.iPerpetualId,
198
+ order.brokerFeeTbps,
199
+ order.traderAddr,
200
+ order.brokerAddr,
201
+ order.fAmount,
202
+ order.fLimitPrice,
203
+ order.fTriggerPrice,
204
+ order.iDeadline,
205
+ order.flags,
206
+ order.fLeverage,
207
+ order.createdTimestamp,
208
+ ]
209
+ )
210
+ );
211
+ let digest = ethers.utils.keccak256(
212
+ abiCoder.encode(["bytes32", "bytes32", "bool"], [domainSeparator, structHash, isNewOrder])
213
+ );
214
+ let digestBuffer = Buffer.from(digest.substring(2, digest.length), "hex");
215
+ return await signer.signMessage(digestBuffer);
216
+ }
217
+ }
@@ -0,0 +1,155 @@
1
+ import WriteAccessHandler from "./writeAccessHandler";
2
+ import { NodeSDKConfig, Order, ORDER_MAX_DURATION_SEC, ZERO_ADDRESS } from "./nodeSDKTypes";
3
+ import PerpetualDataHandler from "./perpetualDataHandler";
4
+ import { ABK64x64ToFloat } from "./d8XMath";
5
+ import { text } from "stream/consumers";
6
+ import { ethers } from "ethers";
7
+ import AccountTrade from "./accountTrade";
8
+ /**
9
+ * BrokerTool.
10
+ * Signature method for brokers
11
+ */
12
+ export default class BrokerTool extends WriteAccessHandler {
13
+ /**
14
+ * Constructor
15
+ * @param config configuration
16
+ * @param privateKey private key of account that trades
17
+ */
18
+ public constructor(config: NodeSDKConfig, privateKey: string) {
19
+ super(config, privateKey);
20
+ }
21
+
22
+ /**
23
+ *
24
+ * @param symbol symbol of the form "ETH-USD-MATIC" or just "MATIC"
25
+ * @returns broker lot size in collateral currency, e.g. in MATIC for symbol ETH-USD-MATIC or MATIC
26
+ */
27
+ public async getLotSize(symbol: string): Promise<number | undefined> {
28
+ if (this.proxyContract == null) {
29
+ throw Error("no proxy contract initialized. Use createProxyInstance().");
30
+ }
31
+ let poolId = PerpetualDataHandler._getPoolIdFromSymbol(symbol, this.poolStaticInfos);
32
+ let pool = await this.proxyContract.getLiquidityPool(poolId);
33
+ let lot = pool?.fBrokerCollateralLotSize;
34
+ if (lot != undefined) {
35
+ lot = ABK64x64ToFloat(pool.fBrokerCollateralLotSize);
36
+ }
37
+ return lot;
38
+ }
39
+
40
+ public async brokerDepositToDefaultFund(symbol: string, lots: number): Promise<ethers.providers.TransactionResponse> {
41
+ if (this.proxyContract == null || this.signer == null) {
42
+ throw Error("no proxy contract or wallet initialized. Use createProxyInstance().");
43
+ }
44
+ let poolId = PerpetualDataHandler._getPoolIdFromSymbol(symbol, this.poolStaticInfos);
45
+ let tx = await this.proxyContract.brokerDepositToDefaultFund(poolId, lots, { gasLimit: this.gasLimit });
46
+ return tx;
47
+ }
48
+
49
+ public async getFeeForBrokerVolume(symbol: string): Promise<number | undefined> {
50
+ if (this.proxyContract == null) {
51
+ throw Error("no proxy contract initialized.");
52
+ }
53
+ let poolId = PerpetualDataHandler._getPoolIdFromSymbol(symbol, this.poolStaticInfos);
54
+ let feeTbps = await this.proxyContract.getFeeForBrokerVolume(poolId, this.traderAddr);
55
+ return feeTbps / 100_000;
56
+ }
57
+
58
+ /**
59
+ *
60
+ * @param symbol symbol of the form "ETH-USD-MATIC" or just "MATIC"
61
+ * @returns number of lots deposited by broker
62
+ */
63
+ public async getBrokerDesignation(symbol: string): Promise<number> {
64
+ if (this.proxyContract == null) {
65
+ throw Error("no proxy contract initialized.");
66
+ }
67
+ let poolId = PerpetualDataHandler._getPoolIdFromSymbol(symbol, this.poolStaticInfos);
68
+ let designation = await this.proxyContract.getBrokerDesignation(poolId, this.traderAddr);
69
+ return designation;
70
+ }
71
+
72
+ /**
73
+ * @param symbol symbol of the form "ETH-USD-MATIC" or just "MATIC"
74
+ * @param lots number of lots for which to get the fee. Defaults to this broker's current deposit if not specified
75
+ * @returns fee in decimals based on given number of lots
76
+ */
77
+ public async getFeeForBrokerDesignation(symbol: string, newLots: number = 0): Promise<number | undefined> {
78
+ if (this.proxyContract == null) {
79
+ throw Error("no proxy contract initialized.");
80
+ }
81
+ if (newLots < 0) {
82
+ throw Error("new lots must be a positive number.");
83
+ }
84
+ let lots = await this.getBrokerDesignation(symbol);
85
+ lots += newLots;
86
+ let feeTbps = await this.proxyContract.getFeeForBrokerDesignation(lots);
87
+ return feeTbps / 100_000;
88
+ }
89
+
90
+ /**
91
+ * @param order order for which to determine the trading fee
92
+ * @param traderAddr address of the trader for whom to determine the fee, defaults to lowest tier
93
+ * @returns fee in decimals (1% is 0.01)
94
+ */
95
+ public async determineExchangeFee(order: Order, traderAddr: string = ZERO_ADDRESS): Promise<number | undefined> {
96
+ if (this.proxyContract == null) {
97
+ throw Error("no proxy contract initialized.");
98
+ }
99
+ // broker does not need to enter address in the order if he's signed in
100
+ if (order.brokerAddr == undefined) {
101
+ if (this.signer == null) {
102
+ throw Error("no wallet initialized.");
103
+ }
104
+ order.brokerAddr = this.traderAddr;
105
+ }
106
+ let scOrder = AccountTrade.toSmartContractOrder(order, traderAddr, this.symbolToPerpStaticInfo);
107
+ let feeTbps = await this.proxyContract.determineExchangeFee(scOrder);
108
+ return feeTbps / 100_000;
109
+ }
110
+
111
+ // public async sign(traderAddr: string, deadline: number, fee: number): Promise<string> {
112
+ // /**
113
+ // * structHash = keccak256(
114
+ // abi.encode(
115
+ // TRADE_BROKER_TYPEHASH,
116
+ // _order.iPerpetualId,
117
+ // _order.brokerFeeTbps,
118
+ // _order.traderAddr,
119
+ // _order.iDeadline
120
+ // )
121
+ // );
122
+ // return structHash;
123
+ // */
124
+ // const NAME = "Perpetual Trade Manager";
125
+ // const DOMAIN_TYPEHASH = ethers.utils.keccak256(
126
+ // Buffer.from("EIP712Domain(string name,uint256 chainId,address verifyingContract)")
127
+ // );
128
+ // let abiCoder = ethers.utils.defaultAbiCoder;
129
+ // let domainSeparator = ethers.utils.keccak256(
130
+ // abiCoder.encode(
131
+ // ["bytes32", "bytes32", "uint256", "address"],
132
+ // [DOMAIN_TYPEHASH, ethers.utils.keccak256(Buffer.from(NAME)), chainId, proxyAddress]
133
+ // )
134
+ // );
135
+ // let digest = ethers.utils.keccak256(
136
+ // abiCoder.encode(["bytes32", "bytes32", "bool"], [domainSeparator, structHash, isNewOrder])
137
+ // );
138
+ // let digestBuffer = Buffer.from(digest.substring(2, digest.length), "hex");
139
+ // return await signer.signMessage(digestBuffer);
140
+ // }
141
+
142
+ /*
143
+ TODO:
144
+ - get lot size DONE
145
+ - purchase n lots:
146
+ brokerDepositToDefaultFund(symbol, amountLots) DONE
147
+ - fees:
148
+ getFeeForBrokerVolume DONE
149
+ determineExchangeFee(order) DONE
150
+ getBrokerDesignation DONE
151
+ getFeeForBrokerDesignation DONE
152
+ - get fee for trader and broker
153
+ - sign {trader address, deadline, broker fee}
154
+ */
155
+ }