@d8x/perpetuals-sdk 0.1.2 → 0.1.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.
package/README.md CHANGED
@@ -33,4 +33,5 @@ Node TypeScript SDK for D8X Perpetual Futures
33
33
  `yarn build`
34
34
  `yarn build:doc`
35
35
  `yarn login`
36
+ `yarn version`
36
37
  `yarn publish`
@@ -218,5 +218,4 @@ export default class AccountTrade extends WriteAccessHandler {
218
218
  * @param {number} amount How much collateral to remove, in units of collateral currency, e.g. MATIC
219
219
  */
220
220
  removeCollateral(symbol: string, amount: number): Promise<ethers.ContractTransaction>;
221
- swapForMockToken(symbol: string, amountToPay: string): Promise<any>;
222
221
  }
@@ -12,7 +12,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
12
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
- const ethers_1 = require("ethers");
16
15
  const d8XMath_1 = require("./d8XMath");
17
16
  const marketData_1 = __importDefault(require("./marketData"));
18
17
  const nodeSDKTypes_1 = require("./nodeSDKTypes");
@@ -342,25 +341,5 @@ class AccountTrade extends writeAccessHandler_1.default {
342
341
  });
343
342
  });
344
343
  }
345
- swapForMockToken(symbol, amountToPay) {
346
- return __awaiter(this, void 0, void 0, function* () {
347
- if (this.signer == null) {
348
- throw Error("no wallet initialized. Use createProxyInstance().");
349
- }
350
- let tokenAddress = this.getMarginTokenFromSymbol(symbol);
351
- if (tokenAddress == undefined) {
352
- throw Error("symbols not found");
353
- }
354
- let tokenToSwap = new Map(Object.entries(require("../config/mockSwap.json")));
355
- let swapAddress = tokenToSwap.get(tokenAddress);
356
- if (swapAddress == undefined) {
357
- throw Error("No swap contract found for symbol.");
358
- }
359
- let contract = new ethers_1.ethers.Contract(swapAddress, nodeSDKTypes_1.MOCK_TOKEN_SWAP_ABI, this.signer.provider);
360
- return yield contract.swapToMockToken({
361
- value: ethers_1.ethers.utils.parseEther(amountToPay),
362
- });
363
- });
364
- }
365
344
  }
366
345
  exports.default = AccountTrade;
@@ -78,7 +78,9 @@ export default class LiquidityProviderTool extends WriteAccessHandler {
78
78
  */
79
79
  addLiquidity(poolSymbolName: string, amountCC: number): Promise<ethers.ContractTransaction>;
80
80
  /**
81
- * Remove liquidity from the pool. The address loses pool shares in return.
81
+ * Initiates a liquidity withdrawal from the pool
82
+ * It triggers a time-delayed unlocking of the given number of pool shares.
83
+ * The amount of pool shares to be unlocked is fixed by this call, but not their value in pool currency.
82
84
  * @param {string} poolSymbolName Name of pool symbol (e.g. MATIC).
83
85
  * @param {string} amountPoolShares Amount in pool-shares, removes everything if > available amount.
84
86
  * @example
@@ -90,13 +92,35 @@ export default class LiquidityProviderTool extends WriteAccessHandler {
90
92
  * const pk: string = <string>process.env.PK;
91
93
  * let lqudtProviderTool = new LiquidityProviderTool(config, pk);
92
94
  * await lqudtProviderTool.createProxyInstance();
93
- * // remove liquidity
94
- * let respRemoveLiquidity = await lqudtProviderTool.removeLiquidity("MATIC", 0.1);
95
+ * // initiate withdrawal
96
+ * let respRemoveLiquidity = await lqudtProviderTool.initiateLiquidityWithdrawal("MATIC", 0.1);
95
97
  * console.log(respRemoveLiquidity);
96
98
  * }
97
99
  * main();
98
100
  *
99
101
  * @return Transaction object.
100
102
  */
101
- removeLiquidity(poolSymbolName: string, amountPoolShares: number): Promise<ethers.providers.TransactionResponse>;
103
+ initiateLiquidityWithdrawal(poolSymbolName: string, amountPoolShares: number): Promise<ethers.providers.TransactionResponse>;
104
+ /**
105
+ * Withdraws as much liquidity as there is available after a call to initiateLiquidityWithdrawal.
106
+ * The address loses pool shares in return.
107
+ * @param poolSymbolName
108
+ * @example
109
+ * import { LiquidityProviderTool, PerpetualDataHandler } from '@d8x/perpetuals-sdk';
110
+ * async function main() {
111
+ * console.log(LiquidityProviderTool);
112
+ * // setup (authentication required, PK is an environment variable with a private key)
113
+ * const config = PerpetualDataHandler.readSDKConfig("testnet");
114
+ * const pk: string = <string>process.env.PK;
115
+ * let lqudtProviderTool = new LiquidityProviderTool(config, pk);
116
+ * await lqudtProviderTool.createProxyInstance();
117
+ * // remove liquidity
118
+ * let respRemoveLiquidity = await lqudtProviderTool.executeLiquidityWithdrawal("MATIC", 0.1);
119
+ * console.log(respRemoveLiquidity);
120
+ * }
121
+ * main();
122
+ *
123
+ * @returns Transaction object.
124
+ */
125
+ executeLiquidityWithdrawal(poolSymbolName: string): Promise<ethers.providers.TransactionResponse>;
102
126
  }
@@ -123,7 +123,9 @@ class LiquidityProviderTool extends writeAccessHandler_1.default {
123
123
  });
124
124
  }
125
125
  /**
126
- * Remove liquidity from the pool. The address loses pool shares in return.
126
+ * Initiates a liquidity withdrawal from the pool
127
+ * It triggers a time-delayed unlocking of the given number of pool shares.
128
+ * The amount of pool shares to be unlocked is fixed by this call, but not their value in pool currency.
127
129
  * @param {string} poolSymbolName Name of pool symbol (e.g. MATIC).
128
130
  * @param {string} amountPoolShares Amount in pool-shares, removes everything if > available amount.
129
131
  * @example
@@ -135,21 +137,54 @@ class LiquidityProviderTool extends writeAccessHandler_1.default {
135
137
  * const pk: string = <string>process.env.PK;
136
138
  * let lqudtProviderTool = new LiquidityProviderTool(config, pk);
137
139
  * await lqudtProviderTool.createProxyInstance();
138
- * // remove liquidity
139
- * let respRemoveLiquidity = await lqudtProviderTool.removeLiquidity("MATIC", 0.1);
140
+ * // initiate withdrawal
141
+ * let respRemoveLiquidity = await lqudtProviderTool.initiateLiquidityWithdrawal("MATIC", 0.1);
140
142
  * console.log(respRemoveLiquidity);
141
143
  * }
142
144
  * main();
143
145
  *
144
146
  * @return Transaction object.
145
147
  */
146
- removeLiquidity(poolSymbolName, amountPoolShares) {
148
+ initiateLiquidityWithdrawal(poolSymbolName, amountPoolShares) {
149
+ return __awaiter(this, void 0, void 0, function* () {
150
+ if (this.proxyContract == null || this.signer == null) {
151
+ throw Error("no proxy contract or wallet initialized. Use createProxyInstance().");
152
+ }
153
+ let poolId = perpetualDataHandler_1.default._getPoolIdFromSymbol(poolSymbolName, this.poolStaticInfos);
154
+ let tx = yield this.proxyContract.withdrawLiquidity(poolId, (0, d8XMath_1.floatToDec18)(amountPoolShares), {
155
+ gasLimit: this.gasLimit,
156
+ });
157
+ return tx;
158
+ });
159
+ }
160
+ /**
161
+ * Withdraws as much liquidity as there is available after a call to initiateLiquidityWithdrawal.
162
+ * The address loses pool shares in return.
163
+ * @param poolSymbolName
164
+ * @example
165
+ * import { LiquidityProviderTool, PerpetualDataHandler } from '@d8x/perpetuals-sdk';
166
+ * async function main() {
167
+ * console.log(LiquidityProviderTool);
168
+ * // setup (authentication required, PK is an environment variable with a private key)
169
+ * const config = PerpetualDataHandler.readSDKConfig("testnet");
170
+ * const pk: string = <string>process.env.PK;
171
+ * let lqudtProviderTool = new LiquidityProviderTool(config, pk);
172
+ * await lqudtProviderTool.createProxyInstance();
173
+ * // remove liquidity
174
+ * let respRemoveLiquidity = await lqudtProviderTool.executeLiquidityWithdrawal("MATIC", 0.1);
175
+ * console.log(respRemoveLiquidity);
176
+ * }
177
+ * main();
178
+ *
179
+ * @returns Transaction object.
180
+ */
181
+ executeLiquidityWithdrawal(poolSymbolName) {
147
182
  return __awaiter(this, void 0, void 0, function* () {
148
183
  if (this.proxyContract == null || this.signer == null) {
149
184
  throw Error("no proxy contract or wallet initialized. Use createProxyInstance().");
150
185
  }
151
186
  let poolId = perpetualDataHandler_1.default._getPoolIdFromSymbol(poolSymbolName, this.poolStaticInfos);
152
- let tx = yield this.proxyContract.removeLiquidity(poolId, (0, d8XMath_1.floatToDec18)(amountPoolShares), {
187
+ let tx = yield this.proxyContract.executeLiquidityWithdrawal(poolId, {
153
188
  gasLimit: this.gasLimit,
154
189
  });
155
190
  return tx;
@@ -279,5 +279,12 @@ export default class MarketData extends PerpetualDataHandler {
279
279
  */
280
280
  static orderIdsOfTrader(traderAddr: string, orderBookContract: ethers.Contract): Promise<string[]>;
281
281
  getAvailableMargin(traderAddr: string, symbol: string, indexPrices?: [number, number]): Promise<number>;
282
+ /**
283
+ * Calculate a type of exchange loyality score based on trader volume
284
+ * @param traderAddr address of the trader
285
+ * @param brokerAddr address of the trader's broker or undefined
286
+ * @returns a loyality score (4 worst, 1 best)
287
+ */
288
+ getTraderLoyalityScore(traderAddr: string, brokerAddr?: string): Promise<number>;
282
289
  static _exchangeInfo(_proxyContract: ethers.Contract, _poolStaticInfos: Array<PoolStaticInfo>, _symbolToPerpStaticInfo: Map<string, PerpetualStaticInfo>, _symbolList: Map<string, string>, _priceFeedGetter: PriceFeeds): Promise<ExchangeInfo>;
283
290
  }
@@ -605,6 +605,47 @@ class MarketData extends perpetualDataHandler_1.default {
605
605
  return balanceCC - initalMarginCC;
606
606
  });
607
607
  }
608
+ /**
609
+ * Calculate a type of exchange loyality score based on trader volume
610
+ * @param traderAddr address of the trader
611
+ * @param brokerAddr address of the trader's broker or undefined
612
+ * @returns a loyality score (4 worst, 1 best)
613
+ */
614
+ getTraderLoyalityScore(traderAddr, brokerAddr) {
615
+ return __awaiter(this, void 0, void 0, function* () {
616
+ if (this.proxyContract == null) {
617
+ throw Error("no proxy contract or wallet initialized. Use createProxyInstance().");
618
+ }
619
+ // loop over all pools and query volumes
620
+ let brokerProm = [];
621
+ let traderProm = [];
622
+ for (let k = 0; k < this.poolStaticInfos.length; k++) {
623
+ if (brokerAddr != "" && brokerAddr != undefined) {
624
+ let brkrVol = this.proxyContract.getCurrentBrokerVolume(this.poolStaticInfos[k].poolId, brokerAddr);
625
+ brokerProm.push(brkrVol);
626
+ }
627
+ let trdrVol = this.proxyContract.getCurrentTraderVolume(this.poolStaticInfos[k].poolId, traderAddr);
628
+ traderProm.push(trdrVol);
629
+ }
630
+ // sum
631
+ let totalBrokerVolume = 0;
632
+ let totalTraderVolume = 0;
633
+ let brkrVol = yield Promise.all(brokerProm);
634
+ let trdrVol = yield Promise.all(traderProm);
635
+ for (let k = 0; k < this.poolStaticInfos.length; k++) {
636
+ if (brokerAddr != "" && brokerAddr != undefined) {
637
+ totalBrokerVolume += (0, d8XMath_1.ABK64x64ToFloat)(brkrVol[k]);
638
+ }
639
+ totalTraderVolume += (0, d8XMath_1.ABK64x64ToFloat)(trdrVol[k]);
640
+ }
641
+ const volumeCap = 500000;
642
+ let score = totalBrokerVolume == 0 ? totalTraderVolume / volumeCap : totalBrokerVolume;
643
+ // 5 different equally spaced categories: (4 is best, 1 worst)
644
+ let rank4 = 1 + Math.floor(Math.min(score, 1 - 1e-15) * 4);
645
+ // desired ranking starts at 4 (worst) and ends at 1 (best)
646
+ return 5 - rank4;
647
+ });
648
+ }
608
649
  static _exchangeInfo(_proxyContract, _poolStaticInfos, _symbolToPerpStaticInfo, _symbolList, _priceFeedGetter) {
609
650
  return __awaiter(this, void 0, void 0, function* () {
610
651
  let nestedPerpetualIDs = yield perpetualDataHandler_1.default.getNestedPerpetualIds(_proxyContract);
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const D8X_SDK_VERSION = "0.1.2";
1
+ export declare const D8X_SDK_VERSION = "0.1.3";
package/dist/version.js CHANGED
@@ -1,4 +1,4 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.D8X_SDK_VERSION = void 0;
4
- exports.D8X_SDK_VERSION = "0.1.2";
4
+ exports.D8X_SDK_VERSION = "0.1.3";
@@ -40,4 +40,12 @@ export default class WriteAccessHandler extends PerpetualDataHandler {
40
40
  * @returns {string} Address of this wallet.
41
41
  */
42
42
  getAddress(): string;
43
+ /**
44
+ * Converts a given amount of chain native currency (test MATIC)
45
+ * into a mock token used for trading on testnet, with a rate of 1:100_000
46
+ * @param symbol Pool margin token e.g. MATIC
47
+ * @param amountToPay Amount in chain currency, e.g. "0.1" for 0.1 MATIC
48
+ * @returns
49
+ */
50
+ swapForMockToken(symbol: string, amountToPay: string): Promise<any>;
43
51
  }
@@ -101,5 +101,32 @@ class WriteAccessHandler extends perpetualDataHandler_1.default {
101
101
  getAddress() {
102
102
  return this.traderAddr;
103
103
  }
104
+ /**
105
+ * Converts a given amount of chain native currency (test MATIC)
106
+ * into a mock token used for trading on testnet, with a rate of 1:100_000
107
+ * @param symbol Pool margin token e.g. MATIC
108
+ * @param amountToPay Amount in chain currency, e.g. "0.1" for 0.1 MATIC
109
+ * @returns
110
+ */
111
+ swapForMockToken(symbol, amountToPay) {
112
+ return __awaiter(this, void 0, void 0, function* () {
113
+ if (this.signer == null) {
114
+ throw Error("no wallet initialized. Use createProxyInstance().");
115
+ }
116
+ let tokenAddress = this.getMarginTokenFromSymbol(symbol);
117
+ if (tokenAddress == undefined) {
118
+ throw Error("symbols not found");
119
+ }
120
+ let tokenToSwap = new Map(Object.entries(require("../config/mockSwap.json")));
121
+ let swapAddress = tokenToSwap.get(tokenAddress);
122
+ if (swapAddress == undefined) {
123
+ throw Error("No swap contract found for symbol.");
124
+ }
125
+ let contract = new ethers_1.ethers.Contract(swapAddress, nodeSDKTypes_1.MOCK_TOKEN_SWAP_ABI, this.signer);
126
+ return yield contract.swapToMockToken({
127
+ value: ethers_1.ethers.utils.parseEther(amountToPay),
128
+ });
129
+ });
130
+ }
104
131
  }
105
132
  exports.default = WriteAccessHandler;
package/package.json CHANGED
@@ -33,7 +33,7 @@
33
33
  },
34
34
  "name": "@d8x/perpetuals-sdk",
35
35
  "description": "Node TypeScript SDK for D8X Perpetual Futures",
36
- "version": "0.1.2",
36
+ "version": "0.1.3",
37
37
  "main": "./dist/index.js",
38
38
  "types": "./dist/index.d.ts",
39
39
  "directories": {
@@ -359,23 +359,4 @@ export default class AccountTrade extends WriteAccessHandler {
359
359
  value: this.PRICE_UPDATE_FEE_GWEI * priceFeedData.priceFeedVaas.length,
360
360
  });
361
361
  }
362
-
363
- public async swapForMockToken(symbol: string, amountToPay: string) {
364
- if (this.signer == null) {
365
- throw Error("no wallet initialized. Use createProxyInstance().");
366
- }
367
- let tokenAddress = this.getMarginTokenFromSymbol(symbol);
368
- if (tokenAddress == undefined) {
369
- throw Error("symbols not found");
370
- }
371
- let tokenToSwap = new Map<string, string>(Object.entries(require("../config/mockSwap.json")));
372
- let swapAddress = tokenToSwap.get(tokenAddress);
373
- if (swapAddress == undefined) {
374
- throw Error("No swap contract found for symbol.");
375
- }
376
- let contract = new ethers.Contract(swapAddress, MOCK_TOKEN_SWAP_ABI, this.signer.provider);
377
- return await contract.swapToMockToken({
378
- value: ethers.utils.parseEther(amountToPay),
379
- });
380
- }
381
362
  }
@@ -116,7 +116,9 @@ export default class LiquidityProviderTool extends WriteAccessHandler {
116
116
  }
117
117
 
118
118
  /**
119
- * Remove liquidity from the pool. The address loses pool shares in return.
119
+ * Initiates a liquidity withdrawal from the pool
120
+ * It triggers a time-delayed unlocking of the given number of pool shares.
121
+ * The amount of pool shares to be unlocked is fixed by this call, but not their value in pool currency.
120
122
  * @param {string} poolSymbolName Name of pool symbol (e.g. MATIC).
121
123
  * @param {string} amountPoolShares Amount in pool-shares, removes everything if > available amount.
122
124
  * @example
@@ -128,15 +130,15 @@ export default class LiquidityProviderTool extends WriteAccessHandler {
128
130
  * const pk: string = <string>process.env.PK;
129
131
  * let lqudtProviderTool = new LiquidityProviderTool(config, pk);
130
132
  * await lqudtProviderTool.createProxyInstance();
131
- * // remove liquidity
132
- * let respRemoveLiquidity = await lqudtProviderTool.removeLiquidity("MATIC", 0.1);
133
+ * // initiate withdrawal
134
+ * let respRemoveLiquidity = await lqudtProviderTool.initiateLiquidityWithdrawal("MATIC", 0.1);
133
135
  * console.log(respRemoveLiquidity);
134
136
  * }
135
137
  * main();
136
138
  *
137
139
  * @return Transaction object.
138
140
  */
139
- public async removeLiquidity(
141
+ public async initiateLiquidityWithdrawal(
140
142
  poolSymbolName: string,
141
143
  amountPoolShares: number
142
144
  ): Promise<ethers.providers.TransactionResponse> {
@@ -144,7 +146,39 @@ export default class LiquidityProviderTool extends WriteAccessHandler {
144
146
  throw Error("no proxy contract or wallet initialized. Use createProxyInstance().");
145
147
  }
146
148
  let poolId = PerpetualDataHandler._getPoolIdFromSymbol(poolSymbolName, this.poolStaticInfos);
147
- let tx = await this.proxyContract.removeLiquidity(poolId, floatToDec18(amountPoolShares), {
149
+ let tx = await this.proxyContract.withdrawLiquidity(poolId, floatToDec18(amountPoolShares), {
150
+ gasLimit: this.gasLimit,
151
+ });
152
+ return tx;
153
+ }
154
+
155
+ /**
156
+ * Withdraws as much liquidity as there is available after a call to initiateLiquidityWithdrawal.
157
+ * The address loses pool shares in return.
158
+ * @param poolSymbolName
159
+ * @example
160
+ * import { LiquidityProviderTool, PerpetualDataHandler } from '@d8x/perpetuals-sdk';
161
+ * async function main() {
162
+ * console.log(LiquidityProviderTool);
163
+ * // setup (authentication required, PK is an environment variable with a private key)
164
+ * const config = PerpetualDataHandler.readSDKConfig("testnet");
165
+ * const pk: string = <string>process.env.PK;
166
+ * let lqudtProviderTool = new LiquidityProviderTool(config, pk);
167
+ * await lqudtProviderTool.createProxyInstance();
168
+ * // remove liquidity
169
+ * let respRemoveLiquidity = await lqudtProviderTool.executeLiquidityWithdrawal("MATIC", 0.1);
170
+ * console.log(respRemoveLiquidity);
171
+ * }
172
+ * main();
173
+ *
174
+ * @returns Transaction object.
175
+ */
176
+ public async executeLiquidityWithdrawal(poolSymbolName: string): Promise<ethers.providers.TransactionResponse> {
177
+ if (this.proxyContract == null || this.signer == null) {
178
+ throw Error("no proxy contract or wallet initialized. Use createProxyInstance().");
179
+ }
180
+ let poolId = PerpetualDataHandler._getPoolIdFromSymbol(poolSymbolName, this.poolStaticInfos);
181
+ let tx = await this.proxyContract.executeLiquidityWithdrawal(poolId, {
148
182
  gasLimit: this.gasLimit,
149
183
  });
150
184
  return tx;
package/src/marketData.ts CHANGED
@@ -750,6 +750,46 @@ export default class MarketData extends PerpetualDataHandler {
750
750
  return balanceCC - initalMarginCC;
751
751
  }
752
752
 
753
+ /**
754
+ * Calculate a type of exchange loyality score based on trader volume
755
+ * @param traderAddr address of the trader
756
+ * @param brokerAddr address of the trader's broker or undefined
757
+ * @returns a loyality score (4 worst, 1 best)
758
+ */
759
+ public async getTraderLoyalityScore(traderAddr: string, brokerAddr?: string) : Promise<number> {
760
+ if (this.proxyContract == null) {
761
+ throw Error("no proxy contract or wallet initialized. Use createProxyInstance().");
762
+ }
763
+ // loop over all pools and query volumes
764
+ let brokerProm : Array<Promise<BigNumber>>= [];
765
+ let traderProm : Array<Promise<BigNumber>>= [];
766
+ for(let k=0; k<this.poolStaticInfos.length; k++) {
767
+ if (brokerAddr!="" && brokerAddr!=undefined) {
768
+ let brkrVol = this.proxyContract.getCurrentBrokerVolume(this.poolStaticInfos[k].poolId, brokerAddr);
769
+ brokerProm.push(brkrVol);
770
+ }
771
+ let trdrVol = this.proxyContract.getCurrentTraderVolume(this.poolStaticInfos[k].poolId, traderAddr);
772
+ traderProm.push(trdrVol);
773
+ }
774
+ // sum
775
+ let totalBrokerVolume = 0;
776
+ let totalTraderVolume = 0;
777
+ let brkrVol = await Promise.all(brokerProm);
778
+ let trdrVol = await Promise.all(traderProm);
779
+ for(let k=0; k<this.poolStaticInfos.length; k++) {
780
+ if (brokerAddr!="" && brokerAddr!=undefined) {
781
+ totalBrokerVolume += ABK64x64ToFloat(brkrVol[k]);
782
+ }
783
+ totalTraderVolume += ABK64x64ToFloat(trdrVol[k]);
784
+ }
785
+ const volumeCap = 500_000;
786
+ let score = totalBrokerVolume==0 ? totalTraderVolume/volumeCap : totalBrokerVolume;
787
+ // 5 different equally spaced categories: (4 is best, 1 worst)
788
+ let rank4 = 1+Math.floor(Math.min(score,1-1e-15)*4);
789
+ // desired ranking starts at 4 (worst) and ends at 1 (best)
790
+ return 5-rank4;
791
+ }
792
+
753
793
  public static async _exchangeInfo(
754
794
  _proxyContract: ethers.Contract,
755
795
  _poolStaticInfos: Array<PoolStaticInfo>,
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const D8X_SDK_VERSION = "0.1.2";
1
+ export const D8X_SDK_VERSION = "0.1.3";
@@ -1,6 +1,6 @@
1
1
  import { BigNumber, ethers } from "ethers";
2
2
  import { floatToDec18 } from "./d8XMath";
3
- import { ERC20_ABI, MAX_UINT_256, NodeSDKConfig } from "./nodeSDKTypes";
3
+ import { ERC20_ABI, MAX_UINT_256, MOCK_TOKEN_SWAP_ABI, NodeSDKConfig } from "./nodeSDKTypes";
4
4
  import PerpetualDataHandler from "./perpetualDataHandler";
5
5
 
6
6
  /**
@@ -93,4 +93,30 @@ export default class WriteAccessHandler extends PerpetualDataHandler {
93
93
  public getAddress(): string {
94
94
  return this.traderAddr;
95
95
  }
96
+
97
+ /**
98
+ * Converts a given amount of chain native currency (test MATIC)
99
+ * into a mock token used for trading on testnet, with a rate of 1:100_000
100
+ * @param symbol Pool margin token e.g. MATIC
101
+ * @param amountToPay Amount in chain currency, e.g. "0.1" for 0.1 MATIC
102
+ * @returns
103
+ */
104
+ public async swapForMockToken(symbol: string, amountToPay: string) {
105
+ if (this.signer == null) {
106
+ throw Error("no wallet initialized. Use createProxyInstance().");
107
+ }
108
+ let tokenAddress = this.getMarginTokenFromSymbol(symbol);
109
+ if (tokenAddress == undefined) {
110
+ throw Error("symbols not found");
111
+ }
112
+ let tokenToSwap = new Map<string, string>(Object.entries(require("../config/mockSwap.json")));
113
+ let swapAddress = tokenToSwap.get(tokenAddress);
114
+ if (swapAddress == undefined) {
115
+ throw Error("No swap contract found for symbol.");
116
+ }
117
+ let contract = new ethers.Contract(swapAddress, MOCK_TOKEN_SWAP_ABI, this.signer);
118
+ return await contract.swapToMockToken({
119
+ value: ethers.utils.parseEther(amountToPay),
120
+ });
121
+ }
96
122
  }