@mento-protocol/mento-sdk 0.1.3 → 0.1.5
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 +9 -65
- package/dist/cjs/limits.d.ts +33 -0
- package/dist/cjs/limits.js +122 -0
- package/dist/cjs/mento.d.ts +44 -9
- package/dist/cjs/mento.js +102 -17
- package/dist/cjs/types.d.ts +21 -0
- package/dist/cjs/utils.d.ts +3 -3
- package/dist/cjs/utils.js +5 -3
- package/dist/esm/limits.d.ts +33 -0
- package/dist/esm/limits.js +115 -0
- package/dist/esm/mento.d.ts +44 -9
- package/dist/esm/mento.js +103 -18
- package/dist/esm/types.d.ts +21 -0
- package/dist/esm/utils.d.ts +3 -3
- package/dist/esm/utils.js +5 -3
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -2,72 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
The official Mento Protocol SDK for interacting with Multi-Collateral Mento smart contracts on the Celo network.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Installation
|
|
6
6
|
|
|
7
|
-
```
|
|
8
|
-
|
|
7
|
+
```sh
|
|
8
|
+
# Install with npm
|
|
9
|
+
npm install @mento-protocol/mento-sdk
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const provider = new providers.JsonRpcProvider(
|
|
14
|
-
'https://baklava-forno.celo-testnet.org'
|
|
15
|
-
)
|
|
16
|
-
const pKey =
|
|
17
|
-
'b214fcf9673dc1a880f8041a8c8952c2dc7daff41fb64cf7715919df095c3fce'
|
|
18
|
-
const wallet = new Wallet(pKey, provider)
|
|
19
|
-
|
|
20
|
-
const mento = await Mento.create(wallet)
|
|
21
|
-
console.log('available pairs: ', await mento.getTradeablePairs())
|
|
22
|
-
/*
|
|
23
|
-
[
|
|
24
|
-
[
|
|
25
|
-
{
|
|
26
|
-
address: '0x62492A644A588FD904270BeD06ad52B9abfEA1aE',
|
|
27
|
-
symbol: 'cUSD'
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
address: '0xdDc9bE57f553fe75752D61606B94CBD7e0264eF8',
|
|
31
|
-
symbol: 'CELO'
|
|
32
|
-
}
|
|
33
|
-
],
|
|
34
|
-
...
|
|
35
|
-
]
|
|
36
|
-
*/
|
|
37
|
-
|
|
38
|
-
// swap 1 CELO for cUSD
|
|
39
|
-
const one = 1
|
|
40
|
-
const tokenIn = '0xdDc9bE57f553fe75752D61606B94CBD7e0264eF8' // CELO
|
|
41
|
-
const tokenOut = '0x62492A644A588FD904270BeD06ad52B9abfEA1aE' // cUSD
|
|
42
|
-
const amountIn = utils.parseUnits(one.toString(), 18)
|
|
43
|
-
const expectedAmountOut = await mento.getAmountOut(
|
|
44
|
-
tokenIn,
|
|
45
|
-
tokenOut,
|
|
46
|
-
utils.parseUnits(one.toString(), 18)
|
|
47
|
-
)
|
|
48
|
-
// 95% of the quote to allow some slippage
|
|
49
|
-
const minAmountOut = expectedAmountOut.mul(95).div(100)
|
|
50
|
-
|
|
51
|
-
// allow the broker contract to spend CELO on behalf of the wallet
|
|
52
|
-
const allowanceTxObj = await mento.increaseTradingAllowance(tokenIn, amountIn)
|
|
53
|
-
const allowanceTx = await wallet.sendTransaction(allowanceTxObj)
|
|
54
|
-
const allowanceReceipt = await allowanceTx.wait()
|
|
55
|
-
console.log('increaseAllowance receipt', allowanceReceipt)
|
|
56
|
-
|
|
57
|
-
// execute the swap
|
|
58
|
-
const swapTxObj = await mento.swapIn(
|
|
59
|
-
tokenIn,
|
|
60
|
-
tokenOut,
|
|
61
|
-
amountIn,
|
|
62
|
-
minAmountOut
|
|
63
|
-
)
|
|
64
|
-
const swapTx = await wallet.sendTransaction(swapTxObj)
|
|
65
|
-
const swapReceipt = await swapTx.wait()
|
|
11
|
+
# Or install with yarn
|
|
12
|
+
yarn add @mento-protocol/mento-sdk
|
|
13
|
+
```
|
|
66
14
|
|
|
67
|
-
|
|
68
|
-
}
|
|
15
|
+
# Learn more
|
|
69
16
|
|
|
70
|
-
|
|
71
|
-
.then(() => console.log('Done'))
|
|
72
|
-
.catch((e) => console.error('Error:', e))
|
|
73
|
-
```
|
|
17
|
+
You can find example usages of the SDK in the [mento-sdk-examples](https://github.com/mento-protocol/mento-sdk-examples) repository. For in-depth documentation and walk through explanations please see the [SDK section](https://docs.mento.org/mento-protocol/developers/sdk) of the Mento docs.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Address, TradingLimit, TradingLimitsConfig, TradingLimitsState } from './types';
|
|
2
|
+
import { Broker } from '@mento-protocol/mento-core-ts';
|
|
3
|
+
/**
|
|
4
|
+
* Returns the limit configuration in the broker for the given exchange and asset
|
|
5
|
+
* @param broker an instance of the broker
|
|
6
|
+
* @param exchangeId the id of the exchange
|
|
7
|
+
* @param asset the address of the limited asset
|
|
8
|
+
* @returns the limit configuration
|
|
9
|
+
*/
|
|
10
|
+
export declare function getLimitsConfig(broker: Broker, exchangeId: string, asset: Address): Promise<TradingLimitsConfig>;
|
|
11
|
+
/**
|
|
12
|
+
* Returns the limit state in the broker for the given exchange and asset
|
|
13
|
+
* @param broker an instance of the broker
|
|
14
|
+
* @param exchangeId the id of the exchange
|
|
15
|
+
* @param asset the address of the limited asset
|
|
16
|
+
* @returns the limit state
|
|
17
|
+
*/
|
|
18
|
+
export declare function getLimitsState(broker: Broker, exchangeId: string, asset: Address): Promise<TradingLimitsState>;
|
|
19
|
+
/**
|
|
20
|
+
* Returns a human-friendly representation of the limits for the given exchange and asset
|
|
21
|
+
* @param broker an instance of the broker
|
|
22
|
+
* @param exchangeId the id of the exchange
|
|
23
|
+
* @param asset the address of the asset with the limit
|
|
24
|
+
* @returns a list of TradingLimit objects
|
|
25
|
+
*/
|
|
26
|
+
export declare function getLimits(broker: Broker, exchangeId: string, asset: Address): Promise<TradingLimit[]>;
|
|
27
|
+
/**
|
|
28
|
+
* Returns the limit id for the given exchange and asset
|
|
29
|
+
* @param exchangeId the id of the exchange
|
|
30
|
+
* @param asset the address of the asset with the limit
|
|
31
|
+
* @returns the limit id
|
|
32
|
+
*/
|
|
33
|
+
export declare function getLimitId(exchangeId: string, asset: Address): string;
|
|
@@ -0,0 +1,122 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.getLimitId = exports.getLimits = exports.getLimitsState = exports.getLimitsConfig = void 0;
|
|
13
|
+
const assert_1 = require("assert");
|
|
14
|
+
const ethers_1 = require("ethers");
|
|
15
|
+
/**
|
|
16
|
+
* Returns the limit configuration in the broker for the given exchange and asset
|
|
17
|
+
* @param broker an instance of the broker
|
|
18
|
+
* @param exchangeId the id of the exchange
|
|
19
|
+
* @param asset the address of the limited asset
|
|
20
|
+
* @returns the limit configuration
|
|
21
|
+
*/
|
|
22
|
+
function getLimitsConfig(broker, exchangeId, asset) {
|
|
23
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
24
|
+
const limitId = getLimitId(exchangeId, asset);
|
|
25
|
+
const cfg = yield broker.tradingLimitsConfig(limitId);
|
|
26
|
+
return {
|
|
27
|
+
timestep0: cfg['timestep0'],
|
|
28
|
+
timestep1: cfg['timestep1'],
|
|
29
|
+
limit0: cfg['limit0'],
|
|
30
|
+
limit1: cfg['limit1'],
|
|
31
|
+
limitGlobal: cfg['limitGlobal'],
|
|
32
|
+
flags: cfg['flags'],
|
|
33
|
+
};
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
exports.getLimitsConfig = getLimitsConfig;
|
|
37
|
+
/**
|
|
38
|
+
* Returns the limit state in the broker for the given exchange and asset
|
|
39
|
+
* @param broker an instance of the broker
|
|
40
|
+
* @param exchangeId the id of the exchange
|
|
41
|
+
* @param asset the address of the limited asset
|
|
42
|
+
* @returns the limit state
|
|
43
|
+
*/
|
|
44
|
+
function getLimitsState(broker, exchangeId, asset) {
|
|
45
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
46
|
+
const limitId = getLimitId(exchangeId, asset);
|
|
47
|
+
const [cfg, state] = yield Promise.all([
|
|
48
|
+
getLimitsConfig(broker, exchangeId, asset),
|
|
49
|
+
broker.tradingLimitsState(limitId),
|
|
50
|
+
]);
|
|
51
|
+
const isL0Enabled = cfg.timestep0 > 0;
|
|
52
|
+
const isL1Enabled = cfg.timestep1 > 0;
|
|
53
|
+
const nowEpoch = Math.floor(Date.now() / 1000);
|
|
54
|
+
const isL0Outdated = isL0Enabled && nowEpoch > state['lastUpdated0'] + cfg.timestep0;
|
|
55
|
+
const isL1Outdated = isL1Enabled && nowEpoch > state['lastUpdated1'] + cfg.timestep1;
|
|
56
|
+
return {
|
|
57
|
+
lastUpdated0: isL0Outdated ? nowEpoch : state['lastUpdated0'],
|
|
58
|
+
lastUpdated1: isL1Outdated ? nowEpoch : state['lastUpdated1'],
|
|
59
|
+
netflow0: isL0Outdated ? 0 : state['netflow0'],
|
|
60
|
+
netflow1: isL1Outdated ? 0 : state['netflow1'],
|
|
61
|
+
netflowGlobal: state['netflowGlobal'],
|
|
62
|
+
};
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
exports.getLimitsState = getLimitsState;
|
|
66
|
+
/**
|
|
67
|
+
* Returns a human-friendly representation of the limits for the given exchange and asset
|
|
68
|
+
* @param broker an instance of the broker
|
|
69
|
+
* @param exchangeId the id of the exchange
|
|
70
|
+
* @param asset the address of the asset with the limit
|
|
71
|
+
* @returns a list of TradingLimit objects
|
|
72
|
+
*/
|
|
73
|
+
function getLimits(broker, exchangeId, asset) {
|
|
74
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
75
|
+
const [cfg, state] = yield Promise.all([
|
|
76
|
+
getLimitsConfig(broker, exchangeId, asset),
|
|
77
|
+
getLimitsState(broker, exchangeId, asset),
|
|
78
|
+
]);
|
|
79
|
+
const limits = [];
|
|
80
|
+
if (cfg.limit0 > 0) {
|
|
81
|
+
limits.push({
|
|
82
|
+
asset: asset,
|
|
83
|
+
maxIn: cfg.limit0 - state.netflow0,
|
|
84
|
+
maxOut: cfg.limit0 + state.netflow0,
|
|
85
|
+
until: state.lastUpdated0 + cfg.timestep0,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
if (cfg.limit1 > 0) {
|
|
89
|
+
limits.push({
|
|
90
|
+
asset: asset,
|
|
91
|
+
maxIn: cfg.limit1 - state.netflow1,
|
|
92
|
+
maxOut: cfg.limit1 + state.netflow1,
|
|
93
|
+
until: state.lastUpdated1 + cfg.timestep1,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
if (cfg.limitGlobal > 0) {
|
|
97
|
+
const timestampIn2030 = 1893456000; // a far away timestamp
|
|
98
|
+
limits.push({
|
|
99
|
+
asset: asset,
|
|
100
|
+
maxIn: cfg.limitGlobal - state.netflowGlobal,
|
|
101
|
+
maxOut: cfg.limitGlobal + state.netflowGlobal,
|
|
102
|
+
until: timestampIn2030,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
return limits;
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
exports.getLimits = getLimits;
|
|
109
|
+
/**
|
|
110
|
+
* Returns the limit id for the given exchange and asset
|
|
111
|
+
* @param exchangeId the id of the exchange
|
|
112
|
+
* @param asset the address of the asset with the limit
|
|
113
|
+
* @returns the limit id
|
|
114
|
+
*/
|
|
115
|
+
function getLimitId(exchangeId, asset) {
|
|
116
|
+
const assetBytes32 = ethers_1.utils.zeroPad(asset, 32);
|
|
117
|
+
const exchangeIdBytes = ethers_1.utils.arrayify(exchangeId);
|
|
118
|
+
const assetBytes = ethers_1.utils.arrayify(assetBytes32);
|
|
119
|
+
(0, assert_1.strict)(exchangeIdBytes.length === assetBytes.length, 'exchangeId and asset0 must be the same length');
|
|
120
|
+
return ethers_1.utils.hexlify(exchangeIdBytes.map((b, i) => b ^ assetBytes[i]));
|
|
121
|
+
}
|
|
122
|
+
exports.getLimitId = getLimitId;
|
package/dist/cjs/mento.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { Address, TradingLimit, TradingLimitsConfig, TradingLimitsState } from './types';
|
|
1
2
|
import { IBroker } from '@mento-protocol/mento-core-ts';
|
|
2
|
-
import { BigNumber,
|
|
3
|
-
import { Address } from './types';
|
|
3
|
+
import { BigNumber, BigNumberish, Signer, providers } from 'ethers';
|
|
4
4
|
export interface Exchange {
|
|
5
5
|
providerAddr: Address;
|
|
6
6
|
id: string;
|
|
@@ -56,7 +56,7 @@ export declare class Mento {
|
|
|
56
56
|
* @param amountOut the amount of tokenOut to be bought
|
|
57
57
|
* @returns the amount of tokenIn to be sold
|
|
58
58
|
*/
|
|
59
|
-
getAmountIn(tokenIn: Address, tokenOut: Address, amountOut:
|
|
59
|
+
getAmountIn(tokenIn: Address, tokenOut: Address, amountOut: BigNumberish): Promise<BigNumber>;
|
|
60
60
|
/**
|
|
61
61
|
* Returns the amount of tokenOut to be bought by selling amountIn of tokenIn
|
|
62
62
|
* @param tokenIn the token to be sold
|
|
@@ -64,14 +64,14 @@ export declare class Mento {
|
|
|
64
64
|
* @param amountIn the amount of tokenIn to be sold
|
|
65
65
|
* @returns the amount of tokenOut to be bought
|
|
66
66
|
*/
|
|
67
|
-
getAmountOut(tokenIn: Address, tokenOut: Address, amountIn:
|
|
67
|
+
getAmountOut(tokenIn: Address, tokenOut: Address, amountIn: BigNumberish): Promise<BigNumber>;
|
|
68
68
|
/**
|
|
69
69
|
* Increases the broker's trading allowance for the given token
|
|
70
70
|
* @param token the token to increase the allowance for
|
|
71
71
|
* @param amount the amount to increase the allowance by
|
|
72
72
|
* @returns the populated TransactionRequest object
|
|
73
73
|
*/
|
|
74
|
-
increaseTradingAllowance(token: Address, amount:
|
|
74
|
+
increaseTradingAllowance(token: Address, amount: BigNumberish): Promise<providers.TransactionRequest>;
|
|
75
75
|
/**
|
|
76
76
|
* Returns a token swap populated tx object with a fixed amount of tokenIn and a minimum amount of tokenOut
|
|
77
77
|
* Submitting the transaction to execute the swap is left to the consumer
|
|
@@ -81,7 +81,7 @@ export declare class Mento {
|
|
|
81
81
|
* @param amountOutMin the minimum amount of tokenOut to be bought
|
|
82
82
|
* @returns the populated TransactionRequest object
|
|
83
83
|
*/
|
|
84
|
-
swapIn(tokenIn: Address, tokenOut: Address, amountIn:
|
|
84
|
+
swapIn(tokenIn: Address, tokenOut: Address, amountIn: BigNumberish, amountOutMin: BigNumberish): Promise<providers.TransactionRequest>;
|
|
85
85
|
/**
|
|
86
86
|
* Returns a token swap populated tx object with a maximum amount of tokenIn and a fixed amount of tokenOut
|
|
87
87
|
* Submitting the transaction to execute the swap is left to the consumer
|
|
@@ -91,7 +91,7 @@ export declare class Mento {
|
|
|
91
91
|
* @param amountInMax the maximum amount of tokenIn to be sold
|
|
92
92
|
* @returns the populated TransactionRequest object
|
|
93
93
|
*/
|
|
94
|
-
swapOut(tokenIn: Address, tokenOut: Address, amountOut:
|
|
94
|
+
swapOut(tokenIn: Address, tokenOut: Address, amountOut: BigNumberish, amountInMax: BigNumberish): Promise<providers.TransactionRequest>;
|
|
95
95
|
/**
|
|
96
96
|
* Returns the mento instance's broker contract
|
|
97
97
|
* @returns broker contract
|
|
@@ -109,9 +109,44 @@ export declare class Mento {
|
|
|
109
109
|
getExchangesForProvider(exchangeProviderAddr: Address): Promise<Exchange[]>;
|
|
110
110
|
/**
|
|
111
111
|
* Returns the Mento exchange (if any) for a given pair of tokens
|
|
112
|
-
* @param token0 the first token
|
|
113
|
-
* @param token1 the second token
|
|
112
|
+
* @param token0 the address of the first token
|
|
113
|
+
* @param token1 the address of the second token
|
|
114
114
|
* @returns exchange
|
|
115
115
|
*/
|
|
116
116
|
getExchangeForTokens(token0: Address, token1: Address): Promise<Exchange>;
|
|
117
|
+
/**
|
|
118
|
+
* Returns the Mento exchange for a given exchange id
|
|
119
|
+
* @param exchangeId the id of the exchange
|
|
120
|
+
* @returns the exchange with the given id
|
|
121
|
+
*/
|
|
122
|
+
getExchangeById(exchangeId: string): Promise<Exchange>;
|
|
123
|
+
/**
|
|
124
|
+
* Returns whether trading is enabled in the given mode for a given exchange id
|
|
125
|
+
* @param exchangeId the id of the exchange
|
|
126
|
+
* @param mode the trading mode
|
|
127
|
+
* @returns true if trading is enabled in the given mode, false otherwise
|
|
128
|
+
*/
|
|
129
|
+
isTradingEnabled(exchangeId: string): Promise<boolean>;
|
|
130
|
+
/**
|
|
131
|
+
* Return the trading limits for a given exchange id. Each limit is an object with the following fields:
|
|
132
|
+
* asset: the address of the asset with the limit
|
|
133
|
+
* maxIn: the maximum amount of the asset that can be sold
|
|
134
|
+
* maxOut: the maximum amount of the asset that can be bought
|
|
135
|
+
* until: the timestamp until which the limit is valid
|
|
136
|
+
* @param exchangeId the id of the exchange
|
|
137
|
+
* @returns the list of trading limits
|
|
138
|
+
*/
|
|
139
|
+
getTradingLimits(exchangeId: string): Promise<TradingLimit[]>;
|
|
140
|
+
/**
|
|
141
|
+
* Returns the trading limits configuration for a given exchange id
|
|
142
|
+
* @param exchangeId the id of the exchange
|
|
143
|
+
* @returns the trading limits configuration
|
|
144
|
+
*/
|
|
145
|
+
getTradingLimitConfig(exchangeId: string): Promise<TradingLimitsConfig>;
|
|
146
|
+
/**
|
|
147
|
+
* Returns the trading limits state for a given exchange id
|
|
148
|
+
* @param exchangeId the id of the exchange
|
|
149
|
+
* @returns the trading limits state
|
|
150
|
+
*/
|
|
151
|
+
getTradingLimitState(exchangeId: string): Promise<TradingLimitsState>;
|
|
117
152
|
}
|
package/dist/cjs/mento.js
CHANGED
|
@@ -13,6 +13,7 @@ exports.Mento = void 0;
|
|
|
13
13
|
const mento_core_ts_1 = require("@mento-protocol/mento-core-ts");
|
|
14
14
|
const ethers_1 = require("ethers");
|
|
15
15
|
const utils_1 = require("./utils");
|
|
16
|
+
const limits_1 = require("./limits");
|
|
16
17
|
const assert_1 = require("assert");
|
|
17
18
|
class Mento {
|
|
18
19
|
/**
|
|
@@ -117,13 +118,15 @@ class Mento {
|
|
|
117
118
|
*/
|
|
118
119
|
increaseTradingAllowance(token, amount) {
|
|
119
120
|
return __awaiter(this, void 0, void 0, function* () {
|
|
120
|
-
if (!ethers_1.Signer.isSigner(this.signerOrProvider)) {
|
|
121
|
-
throw new Error('A signer is required to populate the increaseAllowance tx object');
|
|
122
|
-
}
|
|
123
121
|
const spender = this.broker.address;
|
|
124
122
|
const tx = yield (0, utils_1.increaseAllowance)(token, spender, amount, this.signerOrProvider);
|
|
125
|
-
|
|
126
|
-
|
|
123
|
+
if (ethers_1.Signer.isSigner(this.signerOrProvider)) {
|
|
124
|
+
// The contract call doesn't populate all of the signer fields, so we need an extra call for the signer
|
|
125
|
+
return this.signerOrProvider.populateTransaction(tx);
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
return tx;
|
|
129
|
+
}
|
|
127
130
|
});
|
|
128
131
|
}
|
|
129
132
|
/**
|
|
@@ -137,13 +140,15 @@ class Mento {
|
|
|
137
140
|
*/
|
|
138
141
|
swapIn(tokenIn, tokenOut, amountIn, amountOutMin) {
|
|
139
142
|
return __awaiter(this, void 0, void 0, function* () {
|
|
140
|
-
if (!ethers_1.Signer.isSigner(this.signerOrProvider)) {
|
|
141
|
-
throw new Error('A signer is required to populate the swapIn tx object');
|
|
142
|
-
}
|
|
143
143
|
const exchange = yield this.getExchangeForTokens(tokenIn, tokenOut);
|
|
144
144
|
const tx = yield this.broker.populateTransaction.swapIn(exchange.providerAddr, exchange.id, tokenIn, tokenOut, amountIn, amountOutMin);
|
|
145
|
-
|
|
146
|
-
|
|
145
|
+
if (ethers_1.Signer.isSigner(this.signerOrProvider)) {
|
|
146
|
+
// The contract call doesn't populate all of the signer fields, so we need an extra call for the signer
|
|
147
|
+
return this.signerOrProvider.populateTransaction(tx);
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
return tx;
|
|
151
|
+
}
|
|
147
152
|
});
|
|
148
153
|
}
|
|
149
154
|
/**
|
|
@@ -157,13 +162,15 @@ class Mento {
|
|
|
157
162
|
*/
|
|
158
163
|
swapOut(tokenIn, tokenOut, amountOut, amountInMax) {
|
|
159
164
|
return __awaiter(this, void 0, void 0, function* () {
|
|
160
|
-
if (!ethers_1.Signer.isSigner(this.signerOrProvider)) {
|
|
161
|
-
throw new Error('A signer is required to populate the swapOut tx object');
|
|
162
|
-
}
|
|
163
165
|
const exchange = yield this.getExchangeForTokens(tokenIn, tokenOut);
|
|
164
166
|
const tx = yield this.broker.populateTransaction.swapOut(exchange.providerAddr, exchange.id, tokenIn, tokenOut, amountOut, amountInMax);
|
|
165
|
-
|
|
166
|
-
|
|
167
|
+
if (ethers_1.Signer.isSigner(this.signerOrProvider)) {
|
|
168
|
+
// The contract call doesn't populate all of the signer fields, so we need an extra call for the signer
|
|
169
|
+
return this.signerOrProvider.populateTransaction(tx);
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
return tx;
|
|
173
|
+
}
|
|
167
174
|
});
|
|
168
175
|
}
|
|
169
176
|
/**
|
|
@@ -208,8 +215,8 @@ class Mento {
|
|
|
208
215
|
}
|
|
209
216
|
/**
|
|
210
217
|
* Returns the Mento exchange (if any) for a given pair of tokens
|
|
211
|
-
* @param token0 the first token
|
|
212
|
-
* @param token1 the second token
|
|
218
|
+
* @param token0 the address of the first token
|
|
219
|
+
* @param token1 the address of the second token
|
|
213
220
|
* @returns exchange
|
|
214
221
|
*/
|
|
215
222
|
getExchangeForTokens(token0, token1) {
|
|
@@ -222,5 +229,83 @@ class Mento {
|
|
|
222
229
|
return exchanges[0];
|
|
223
230
|
});
|
|
224
231
|
}
|
|
232
|
+
/**
|
|
233
|
+
* Returns the Mento exchange for a given exchange id
|
|
234
|
+
* @param exchangeId the id of the exchange
|
|
235
|
+
* @returns the exchange with the given id
|
|
236
|
+
*/
|
|
237
|
+
getExchangeById(exchangeId) {
|
|
238
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
239
|
+
const exchanges = (yield this.getExchanges()).filter((e) => e.id === exchangeId);
|
|
240
|
+
if (exchanges.length === 0) {
|
|
241
|
+
throw Error(`No exchange found for id ${exchangeId}`);
|
|
242
|
+
}
|
|
243
|
+
(0, assert_1.strict)(exchanges.length === 1, `More than one exchange found with id ${exchangeId}`);
|
|
244
|
+
return exchanges[0];
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Returns whether trading is enabled in the given mode for a given exchange id
|
|
249
|
+
* @param exchangeId the id of the exchange
|
|
250
|
+
* @param mode the trading mode
|
|
251
|
+
* @returns true if trading is enabled in the given mode, false otherwise
|
|
252
|
+
*/
|
|
253
|
+
isTradingEnabled(exchangeId) {
|
|
254
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
255
|
+
const exchange = yield this.getExchangeById(exchangeId);
|
|
256
|
+
const biPoolManager = mento_core_ts_1.BiPoolManager__factory.connect(exchange.providerAddr, this.signerOrProvider);
|
|
257
|
+
const [breakerBoxAddr, exchangeConfig] = yield Promise.all([
|
|
258
|
+
biPoolManager.breakerBox(),
|
|
259
|
+
biPoolManager.getPoolExchange(exchangeId),
|
|
260
|
+
]);
|
|
261
|
+
const breakerBox = mento_core_ts_1.IBreakerBox__factory.connect(breakerBoxAddr, this.signerOrProvider);
|
|
262
|
+
const currentMode = yield breakerBox.getRateFeedTradingMode(exchangeConfig.config.referenceRateFeedID);
|
|
263
|
+
const BI_DIRECTIONAL_TRADING_MODE = 0;
|
|
264
|
+
return currentMode.toNumber() == BI_DIRECTIONAL_TRADING_MODE;
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Return the trading limits for a given exchange id. Each limit is an object with the following fields:
|
|
269
|
+
* asset: the address of the asset with the limit
|
|
270
|
+
* maxIn: the maximum amount of the asset that can be sold
|
|
271
|
+
* maxOut: the maximum amount of the asset that can be bought
|
|
272
|
+
* until: the timestamp until which the limit is valid
|
|
273
|
+
* @param exchangeId the id of the exchange
|
|
274
|
+
* @returns the list of trading limits
|
|
275
|
+
*/
|
|
276
|
+
getTradingLimits(exchangeId) {
|
|
277
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
278
|
+
const exchange = yield this.getExchangeById(exchangeId);
|
|
279
|
+
const broker = mento_core_ts_1.Broker__factory.connect(this.broker.address, this.signerOrProvider);
|
|
280
|
+
const assetWithLimit = exchange.assets[0]; // currently limits are configured only on asset0
|
|
281
|
+
return (0, limits_1.getLimits)(broker, exchangeId, assetWithLimit);
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Returns the trading limits configuration for a given exchange id
|
|
286
|
+
* @param exchangeId the id of the exchange
|
|
287
|
+
* @returns the trading limits configuration
|
|
288
|
+
*/
|
|
289
|
+
getTradingLimitConfig(exchangeId) {
|
|
290
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
291
|
+
const exchange = yield this.getExchangeById(exchangeId);
|
|
292
|
+
const broker = mento_core_ts_1.Broker__factory.connect(this.broker.address, this.signerOrProvider);
|
|
293
|
+
const assetWithLimit = exchange.assets[0]; // currently limits are configured only on asset0
|
|
294
|
+
return (0, limits_1.getLimitsConfig)(broker, exchangeId, assetWithLimit);
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Returns the trading limits state for a given exchange id
|
|
299
|
+
* @param exchangeId the id of the exchange
|
|
300
|
+
* @returns the trading limits state
|
|
301
|
+
*/
|
|
302
|
+
getTradingLimitState(exchangeId) {
|
|
303
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
304
|
+
const exchange = yield this.getExchangeById(exchangeId);
|
|
305
|
+
const broker = mento_core_ts_1.Broker__factory.connect(this.broker.address, this.signerOrProvider);
|
|
306
|
+
const assetWithLimit = exchange.assets[0]; // currently limits are configured only on asset0
|
|
307
|
+
return (0, limits_1.getLimitsState)(broker, exchangeId, assetWithLimit);
|
|
308
|
+
});
|
|
309
|
+
}
|
|
225
310
|
}
|
|
226
311
|
exports.Mento = Mento;
|
package/dist/cjs/types.d.ts
CHANGED
|
@@ -1 +1,22 @@
|
|
|
1
1
|
export type Address = string;
|
|
2
|
+
export interface TradingLimit {
|
|
3
|
+
asset: Address;
|
|
4
|
+
maxIn: number;
|
|
5
|
+
maxOut: number;
|
|
6
|
+
until: number;
|
|
7
|
+
}
|
|
8
|
+
export interface TradingLimitsConfig {
|
|
9
|
+
timestep0: number;
|
|
10
|
+
timestep1: number;
|
|
11
|
+
limit0: number;
|
|
12
|
+
limit1: number;
|
|
13
|
+
limitGlobal: number;
|
|
14
|
+
flags: number;
|
|
15
|
+
}
|
|
16
|
+
export interface TradingLimitsState {
|
|
17
|
+
lastUpdated0: number;
|
|
18
|
+
lastUpdated1: number;
|
|
19
|
+
netflow0: number;
|
|
20
|
+
netflow1: number;
|
|
21
|
+
netflowGlobal: number;
|
|
22
|
+
}
|
package/dist/cjs/utils.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BigNumberish, providers, Signer } from 'ethers';
|
|
2
2
|
import { Address } from './types';
|
|
3
3
|
/**
|
|
4
4
|
* Ensures that given signer is truly a a connected signer
|
|
@@ -30,7 +30,7 @@ export declare function getSymbolFromTokenAddress(tokenAddr: Address, signerOrPr
|
|
|
30
30
|
* @param tokenAddr the address of the erc20 token
|
|
31
31
|
* @param spender the address of the spender
|
|
32
32
|
* @param amount the amount to increase the allowance by
|
|
33
|
-
* @param
|
|
33
|
+
* @param signerOrProvider an ethers signer or provider
|
|
34
34
|
* @returns the populated TransactionRequest object
|
|
35
35
|
*/
|
|
36
|
-
export declare function increaseAllowance(tokenAddr: string, spender: string, amount:
|
|
36
|
+
export declare function increaseAllowance(tokenAddr: string, spender: string, amount: BigNumberish, signerOrProvider: Signer | providers.Provider): Promise<providers.TransactionRequest>;
|
package/dist/cjs/utils.js
CHANGED
|
@@ -81,15 +81,17 @@ exports.getSymbolFromTokenAddress = getSymbolFromTokenAddress;
|
|
|
81
81
|
* @param tokenAddr the address of the erc20 token
|
|
82
82
|
* @param spender the address of the spender
|
|
83
83
|
* @param amount the amount to increase the allowance by
|
|
84
|
-
* @param
|
|
84
|
+
* @param signerOrProvider an ethers signer or provider
|
|
85
85
|
* @returns the populated TransactionRequest object
|
|
86
86
|
*/
|
|
87
|
-
function increaseAllowance(tokenAddr, spender, amount,
|
|
87
|
+
function increaseAllowance(tokenAddr, spender, amount, signerOrProvider) {
|
|
88
88
|
return __awaiter(this, void 0, void 0, function* () {
|
|
89
89
|
const abi = [
|
|
90
90
|
'function increaseAllowance(address spender, uint256 value) external returns (bool)',
|
|
91
91
|
];
|
|
92
|
-
|
|
92
|
+
// TODO, not all ERC-20 contracts support increaseAllowance
|
|
93
|
+
// Add a check for that here
|
|
94
|
+
const contract = new ethers_1.Contract(tokenAddr, abi, signerOrProvider);
|
|
93
95
|
return yield contract.populateTransaction.increaseAllowance(spender, amount);
|
|
94
96
|
});
|
|
95
97
|
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Address, TradingLimit, TradingLimitsConfig, TradingLimitsState } from './types';
|
|
2
|
+
import { Broker } from '@mento-protocol/mento-core-ts';
|
|
3
|
+
/**
|
|
4
|
+
* Returns the limit configuration in the broker for the given exchange and asset
|
|
5
|
+
* @param broker an instance of the broker
|
|
6
|
+
* @param exchangeId the id of the exchange
|
|
7
|
+
* @param asset the address of the limited asset
|
|
8
|
+
* @returns the limit configuration
|
|
9
|
+
*/
|
|
10
|
+
export declare function getLimitsConfig(broker: Broker, exchangeId: string, asset: Address): Promise<TradingLimitsConfig>;
|
|
11
|
+
/**
|
|
12
|
+
* Returns the limit state in the broker for the given exchange and asset
|
|
13
|
+
* @param broker an instance of the broker
|
|
14
|
+
* @param exchangeId the id of the exchange
|
|
15
|
+
* @param asset the address of the limited asset
|
|
16
|
+
* @returns the limit state
|
|
17
|
+
*/
|
|
18
|
+
export declare function getLimitsState(broker: Broker, exchangeId: string, asset: Address): Promise<TradingLimitsState>;
|
|
19
|
+
/**
|
|
20
|
+
* Returns a human-friendly representation of the limits for the given exchange and asset
|
|
21
|
+
* @param broker an instance of the broker
|
|
22
|
+
* @param exchangeId the id of the exchange
|
|
23
|
+
* @param asset the address of the asset with the limit
|
|
24
|
+
* @returns a list of TradingLimit objects
|
|
25
|
+
*/
|
|
26
|
+
export declare function getLimits(broker: Broker, exchangeId: string, asset: Address): Promise<TradingLimit[]>;
|
|
27
|
+
/**
|
|
28
|
+
* Returns the limit id for the given exchange and asset
|
|
29
|
+
* @param exchangeId the id of the exchange
|
|
30
|
+
* @param asset the address of the asset with the limit
|
|
31
|
+
* @returns the limit id
|
|
32
|
+
*/
|
|
33
|
+
export declare function getLimitId(exchangeId: string, asset: Address): string;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { strict as assert } from 'assert';
|
|
11
|
+
import { utils } from 'ethers';
|
|
12
|
+
/**
|
|
13
|
+
* Returns the limit configuration in the broker for the given exchange and asset
|
|
14
|
+
* @param broker an instance of the broker
|
|
15
|
+
* @param exchangeId the id of the exchange
|
|
16
|
+
* @param asset the address of the limited asset
|
|
17
|
+
* @returns the limit configuration
|
|
18
|
+
*/
|
|
19
|
+
export function getLimitsConfig(broker, exchangeId, asset) {
|
|
20
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
21
|
+
const limitId = getLimitId(exchangeId, asset);
|
|
22
|
+
const cfg = yield broker.tradingLimitsConfig(limitId);
|
|
23
|
+
return {
|
|
24
|
+
timestep0: cfg['timestep0'],
|
|
25
|
+
timestep1: cfg['timestep1'],
|
|
26
|
+
limit0: cfg['limit0'],
|
|
27
|
+
limit1: cfg['limit1'],
|
|
28
|
+
limitGlobal: cfg['limitGlobal'],
|
|
29
|
+
flags: cfg['flags'],
|
|
30
|
+
};
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Returns the limit state in the broker for the given exchange and asset
|
|
35
|
+
* @param broker an instance of the broker
|
|
36
|
+
* @param exchangeId the id of the exchange
|
|
37
|
+
* @param asset the address of the limited asset
|
|
38
|
+
* @returns the limit state
|
|
39
|
+
*/
|
|
40
|
+
export function getLimitsState(broker, exchangeId, asset) {
|
|
41
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
42
|
+
const limitId = getLimitId(exchangeId, asset);
|
|
43
|
+
const [cfg, state] = yield Promise.all([
|
|
44
|
+
getLimitsConfig(broker, exchangeId, asset),
|
|
45
|
+
broker.tradingLimitsState(limitId),
|
|
46
|
+
]);
|
|
47
|
+
const isL0Enabled = cfg.timestep0 > 0;
|
|
48
|
+
const isL1Enabled = cfg.timestep1 > 0;
|
|
49
|
+
const nowEpoch = Math.floor(Date.now() / 1000);
|
|
50
|
+
const isL0Outdated = isL0Enabled && nowEpoch > state['lastUpdated0'] + cfg.timestep0;
|
|
51
|
+
const isL1Outdated = isL1Enabled && nowEpoch > state['lastUpdated1'] + cfg.timestep1;
|
|
52
|
+
return {
|
|
53
|
+
lastUpdated0: isL0Outdated ? nowEpoch : state['lastUpdated0'],
|
|
54
|
+
lastUpdated1: isL1Outdated ? nowEpoch : state['lastUpdated1'],
|
|
55
|
+
netflow0: isL0Outdated ? 0 : state['netflow0'],
|
|
56
|
+
netflow1: isL1Outdated ? 0 : state['netflow1'],
|
|
57
|
+
netflowGlobal: state['netflowGlobal'],
|
|
58
|
+
};
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Returns a human-friendly representation of the limits for the given exchange and asset
|
|
63
|
+
* @param broker an instance of the broker
|
|
64
|
+
* @param exchangeId the id of the exchange
|
|
65
|
+
* @param asset the address of the asset with the limit
|
|
66
|
+
* @returns a list of TradingLimit objects
|
|
67
|
+
*/
|
|
68
|
+
export function getLimits(broker, exchangeId, asset) {
|
|
69
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
70
|
+
const [cfg, state] = yield Promise.all([
|
|
71
|
+
getLimitsConfig(broker, exchangeId, asset),
|
|
72
|
+
getLimitsState(broker, exchangeId, asset),
|
|
73
|
+
]);
|
|
74
|
+
const limits = [];
|
|
75
|
+
if (cfg.limit0 > 0) {
|
|
76
|
+
limits.push({
|
|
77
|
+
asset: asset,
|
|
78
|
+
maxIn: cfg.limit0 - state.netflow0,
|
|
79
|
+
maxOut: cfg.limit0 + state.netflow0,
|
|
80
|
+
until: state.lastUpdated0 + cfg.timestep0,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
if (cfg.limit1 > 0) {
|
|
84
|
+
limits.push({
|
|
85
|
+
asset: asset,
|
|
86
|
+
maxIn: cfg.limit1 - state.netflow1,
|
|
87
|
+
maxOut: cfg.limit1 + state.netflow1,
|
|
88
|
+
until: state.lastUpdated1 + cfg.timestep1,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
if (cfg.limitGlobal > 0) {
|
|
92
|
+
const timestampIn2030 = 1893456000; // a far away timestamp
|
|
93
|
+
limits.push({
|
|
94
|
+
asset: asset,
|
|
95
|
+
maxIn: cfg.limitGlobal - state.netflowGlobal,
|
|
96
|
+
maxOut: cfg.limitGlobal + state.netflowGlobal,
|
|
97
|
+
until: timestampIn2030,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
return limits;
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Returns the limit id for the given exchange and asset
|
|
105
|
+
* @param exchangeId the id of the exchange
|
|
106
|
+
* @param asset the address of the asset with the limit
|
|
107
|
+
* @returns the limit id
|
|
108
|
+
*/
|
|
109
|
+
export function getLimitId(exchangeId, asset) {
|
|
110
|
+
const assetBytes32 = utils.zeroPad(asset, 32);
|
|
111
|
+
const exchangeIdBytes = utils.arrayify(exchangeId);
|
|
112
|
+
const assetBytes = utils.arrayify(assetBytes32);
|
|
113
|
+
assert(exchangeIdBytes.length === assetBytes.length, 'exchangeId and asset0 must be the same length');
|
|
114
|
+
return utils.hexlify(exchangeIdBytes.map((b, i) => b ^ assetBytes[i]));
|
|
115
|
+
}
|
package/dist/esm/mento.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { Address, TradingLimit, TradingLimitsConfig, TradingLimitsState } from './types';
|
|
1
2
|
import { IBroker } from '@mento-protocol/mento-core-ts';
|
|
2
|
-
import { BigNumber,
|
|
3
|
-
import { Address } from './types';
|
|
3
|
+
import { BigNumber, BigNumberish, Signer, providers } from 'ethers';
|
|
4
4
|
export interface Exchange {
|
|
5
5
|
providerAddr: Address;
|
|
6
6
|
id: string;
|
|
@@ -56,7 +56,7 @@ export declare class Mento {
|
|
|
56
56
|
* @param amountOut the amount of tokenOut to be bought
|
|
57
57
|
* @returns the amount of tokenIn to be sold
|
|
58
58
|
*/
|
|
59
|
-
getAmountIn(tokenIn: Address, tokenOut: Address, amountOut:
|
|
59
|
+
getAmountIn(tokenIn: Address, tokenOut: Address, amountOut: BigNumberish): Promise<BigNumber>;
|
|
60
60
|
/**
|
|
61
61
|
* Returns the amount of tokenOut to be bought by selling amountIn of tokenIn
|
|
62
62
|
* @param tokenIn the token to be sold
|
|
@@ -64,14 +64,14 @@ export declare class Mento {
|
|
|
64
64
|
* @param amountIn the amount of tokenIn to be sold
|
|
65
65
|
* @returns the amount of tokenOut to be bought
|
|
66
66
|
*/
|
|
67
|
-
getAmountOut(tokenIn: Address, tokenOut: Address, amountIn:
|
|
67
|
+
getAmountOut(tokenIn: Address, tokenOut: Address, amountIn: BigNumberish): Promise<BigNumber>;
|
|
68
68
|
/**
|
|
69
69
|
* Increases the broker's trading allowance for the given token
|
|
70
70
|
* @param token the token to increase the allowance for
|
|
71
71
|
* @param amount the amount to increase the allowance by
|
|
72
72
|
* @returns the populated TransactionRequest object
|
|
73
73
|
*/
|
|
74
|
-
increaseTradingAllowance(token: Address, amount:
|
|
74
|
+
increaseTradingAllowance(token: Address, amount: BigNumberish): Promise<providers.TransactionRequest>;
|
|
75
75
|
/**
|
|
76
76
|
* Returns a token swap populated tx object with a fixed amount of tokenIn and a minimum amount of tokenOut
|
|
77
77
|
* Submitting the transaction to execute the swap is left to the consumer
|
|
@@ -81,7 +81,7 @@ export declare class Mento {
|
|
|
81
81
|
* @param amountOutMin the minimum amount of tokenOut to be bought
|
|
82
82
|
* @returns the populated TransactionRequest object
|
|
83
83
|
*/
|
|
84
|
-
swapIn(tokenIn: Address, tokenOut: Address, amountIn:
|
|
84
|
+
swapIn(tokenIn: Address, tokenOut: Address, amountIn: BigNumberish, amountOutMin: BigNumberish): Promise<providers.TransactionRequest>;
|
|
85
85
|
/**
|
|
86
86
|
* Returns a token swap populated tx object with a maximum amount of tokenIn and a fixed amount of tokenOut
|
|
87
87
|
* Submitting the transaction to execute the swap is left to the consumer
|
|
@@ -91,7 +91,7 @@ export declare class Mento {
|
|
|
91
91
|
* @param amountInMax the maximum amount of tokenIn to be sold
|
|
92
92
|
* @returns the populated TransactionRequest object
|
|
93
93
|
*/
|
|
94
|
-
swapOut(tokenIn: Address, tokenOut: Address, amountOut:
|
|
94
|
+
swapOut(tokenIn: Address, tokenOut: Address, amountOut: BigNumberish, amountInMax: BigNumberish): Promise<providers.TransactionRequest>;
|
|
95
95
|
/**
|
|
96
96
|
* Returns the mento instance's broker contract
|
|
97
97
|
* @returns broker contract
|
|
@@ -109,9 +109,44 @@ export declare class Mento {
|
|
|
109
109
|
getExchangesForProvider(exchangeProviderAddr: Address): Promise<Exchange[]>;
|
|
110
110
|
/**
|
|
111
111
|
* Returns the Mento exchange (if any) for a given pair of tokens
|
|
112
|
-
* @param token0 the first token
|
|
113
|
-
* @param token1 the second token
|
|
112
|
+
* @param token0 the address of the first token
|
|
113
|
+
* @param token1 the address of the second token
|
|
114
114
|
* @returns exchange
|
|
115
115
|
*/
|
|
116
116
|
getExchangeForTokens(token0: Address, token1: Address): Promise<Exchange>;
|
|
117
|
+
/**
|
|
118
|
+
* Returns the Mento exchange for a given exchange id
|
|
119
|
+
* @param exchangeId the id of the exchange
|
|
120
|
+
* @returns the exchange with the given id
|
|
121
|
+
*/
|
|
122
|
+
getExchangeById(exchangeId: string): Promise<Exchange>;
|
|
123
|
+
/**
|
|
124
|
+
* Returns whether trading is enabled in the given mode for a given exchange id
|
|
125
|
+
* @param exchangeId the id of the exchange
|
|
126
|
+
* @param mode the trading mode
|
|
127
|
+
* @returns true if trading is enabled in the given mode, false otherwise
|
|
128
|
+
*/
|
|
129
|
+
isTradingEnabled(exchangeId: string): Promise<boolean>;
|
|
130
|
+
/**
|
|
131
|
+
* Return the trading limits for a given exchange id. Each limit is an object with the following fields:
|
|
132
|
+
* asset: the address of the asset with the limit
|
|
133
|
+
* maxIn: the maximum amount of the asset that can be sold
|
|
134
|
+
* maxOut: the maximum amount of the asset that can be bought
|
|
135
|
+
* until: the timestamp until which the limit is valid
|
|
136
|
+
* @param exchangeId the id of the exchange
|
|
137
|
+
* @returns the list of trading limits
|
|
138
|
+
*/
|
|
139
|
+
getTradingLimits(exchangeId: string): Promise<TradingLimit[]>;
|
|
140
|
+
/**
|
|
141
|
+
* Returns the trading limits configuration for a given exchange id
|
|
142
|
+
* @param exchangeId the id of the exchange
|
|
143
|
+
* @returns the trading limits configuration
|
|
144
|
+
*/
|
|
145
|
+
getTradingLimitConfig(exchangeId: string): Promise<TradingLimitsConfig>;
|
|
146
|
+
/**
|
|
147
|
+
* Returns the trading limits state for a given exchange id
|
|
148
|
+
* @param exchangeId the id of the exchange
|
|
149
|
+
* @returns the trading limits state
|
|
150
|
+
*/
|
|
151
|
+
getTradingLimitState(exchangeId: string): Promise<TradingLimitsState>;
|
|
117
152
|
}
|
package/dist/esm/mento.js
CHANGED
|
@@ -7,9 +7,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import { IBroker__factory, IExchangeProvider__factory, } from '@mento-protocol/mento-core-ts';
|
|
10
|
+
import { BiPoolManager__factory, Broker__factory, IBreakerBox__factory, IBroker__factory, IExchangeProvider__factory, } from '@mento-protocol/mento-core-ts';
|
|
11
11
|
import { Signer } from 'ethers';
|
|
12
12
|
import { getBrokerAddressFromRegistry, getSymbolFromTokenAddress, increaseAllowance, validateSigner, validateSignerOrProvider, } from './utils';
|
|
13
|
+
import { getLimits, getLimitsConfig, getLimitsState } from './limits';
|
|
13
14
|
import { strict as assert } from 'assert';
|
|
14
15
|
export class Mento {
|
|
15
16
|
/**
|
|
@@ -114,13 +115,15 @@ export class Mento {
|
|
|
114
115
|
*/
|
|
115
116
|
increaseTradingAllowance(token, amount) {
|
|
116
117
|
return __awaiter(this, void 0, void 0, function* () {
|
|
117
|
-
if (!Signer.isSigner(this.signerOrProvider)) {
|
|
118
|
-
throw new Error('A signer is required to populate the increaseAllowance tx object');
|
|
119
|
-
}
|
|
120
118
|
const spender = this.broker.address;
|
|
121
119
|
const tx = yield increaseAllowance(token, spender, amount, this.signerOrProvider);
|
|
122
|
-
|
|
123
|
-
|
|
120
|
+
if (Signer.isSigner(this.signerOrProvider)) {
|
|
121
|
+
// The contract call doesn't populate all of the signer fields, so we need an extra call for the signer
|
|
122
|
+
return this.signerOrProvider.populateTransaction(tx);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
return tx;
|
|
126
|
+
}
|
|
124
127
|
});
|
|
125
128
|
}
|
|
126
129
|
/**
|
|
@@ -134,13 +137,15 @@ export class Mento {
|
|
|
134
137
|
*/
|
|
135
138
|
swapIn(tokenIn, tokenOut, amountIn, amountOutMin) {
|
|
136
139
|
return __awaiter(this, void 0, void 0, function* () {
|
|
137
|
-
if (!Signer.isSigner(this.signerOrProvider)) {
|
|
138
|
-
throw new Error('A signer is required to populate the swapIn tx object');
|
|
139
|
-
}
|
|
140
140
|
const exchange = yield this.getExchangeForTokens(tokenIn, tokenOut);
|
|
141
141
|
const tx = yield this.broker.populateTransaction.swapIn(exchange.providerAddr, exchange.id, tokenIn, tokenOut, amountIn, amountOutMin);
|
|
142
|
-
|
|
143
|
-
|
|
142
|
+
if (Signer.isSigner(this.signerOrProvider)) {
|
|
143
|
+
// The contract call doesn't populate all of the signer fields, so we need an extra call for the signer
|
|
144
|
+
return this.signerOrProvider.populateTransaction(tx);
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
return tx;
|
|
148
|
+
}
|
|
144
149
|
});
|
|
145
150
|
}
|
|
146
151
|
/**
|
|
@@ -154,13 +159,15 @@ export class Mento {
|
|
|
154
159
|
*/
|
|
155
160
|
swapOut(tokenIn, tokenOut, amountOut, amountInMax) {
|
|
156
161
|
return __awaiter(this, void 0, void 0, function* () {
|
|
157
|
-
if (!Signer.isSigner(this.signerOrProvider)) {
|
|
158
|
-
throw new Error('A signer is required to populate the swapOut tx object');
|
|
159
|
-
}
|
|
160
162
|
const exchange = yield this.getExchangeForTokens(tokenIn, tokenOut);
|
|
161
163
|
const tx = yield this.broker.populateTransaction.swapOut(exchange.providerAddr, exchange.id, tokenIn, tokenOut, amountOut, amountInMax);
|
|
162
|
-
|
|
163
|
-
|
|
164
|
+
if (Signer.isSigner(this.signerOrProvider)) {
|
|
165
|
+
// The contract call doesn't populate all of the signer fields, so we need an extra call for the signer
|
|
166
|
+
return this.signerOrProvider.populateTransaction(tx);
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
return tx;
|
|
170
|
+
}
|
|
164
171
|
});
|
|
165
172
|
}
|
|
166
173
|
/**
|
|
@@ -205,8 +212,8 @@ export class Mento {
|
|
|
205
212
|
}
|
|
206
213
|
/**
|
|
207
214
|
* Returns the Mento exchange (if any) for a given pair of tokens
|
|
208
|
-
* @param token0 the first token
|
|
209
|
-
* @param token1 the second token
|
|
215
|
+
* @param token0 the address of the first token
|
|
216
|
+
* @param token1 the address of the second token
|
|
210
217
|
* @returns exchange
|
|
211
218
|
*/
|
|
212
219
|
getExchangeForTokens(token0, token1) {
|
|
@@ -219,4 +226,82 @@ export class Mento {
|
|
|
219
226
|
return exchanges[0];
|
|
220
227
|
});
|
|
221
228
|
}
|
|
229
|
+
/**
|
|
230
|
+
* Returns the Mento exchange for a given exchange id
|
|
231
|
+
* @param exchangeId the id of the exchange
|
|
232
|
+
* @returns the exchange with the given id
|
|
233
|
+
*/
|
|
234
|
+
getExchangeById(exchangeId) {
|
|
235
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
236
|
+
const exchanges = (yield this.getExchanges()).filter((e) => e.id === exchangeId);
|
|
237
|
+
if (exchanges.length === 0) {
|
|
238
|
+
throw Error(`No exchange found for id ${exchangeId}`);
|
|
239
|
+
}
|
|
240
|
+
assert(exchanges.length === 1, `More than one exchange found with id ${exchangeId}`);
|
|
241
|
+
return exchanges[0];
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Returns whether trading is enabled in the given mode for a given exchange id
|
|
246
|
+
* @param exchangeId the id of the exchange
|
|
247
|
+
* @param mode the trading mode
|
|
248
|
+
* @returns true if trading is enabled in the given mode, false otherwise
|
|
249
|
+
*/
|
|
250
|
+
isTradingEnabled(exchangeId) {
|
|
251
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
252
|
+
const exchange = yield this.getExchangeById(exchangeId);
|
|
253
|
+
const biPoolManager = BiPoolManager__factory.connect(exchange.providerAddr, this.signerOrProvider);
|
|
254
|
+
const [breakerBoxAddr, exchangeConfig] = yield Promise.all([
|
|
255
|
+
biPoolManager.breakerBox(),
|
|
256
|
+
biPoolManager.getPoolExchange(exchangeId),
|
|
257
|
+
]);
|
|
258
|
+
const breakerBox = IBreakerBox__factory.connect(breakerBoxAddr, this.signerOrProvider);
|
|
259
|
+
const currentMode = yield breakerBox.getRateFeedTradingMode(exchangeConfig.config.referenceRateFeedID);
|
|
260
|
+
const BI_DIRECTIONAL_TRADING_MODE = 0;
|
|
261
|
+
return currentMode.toNumber() == BI_DIRECTIONAL_TRADING_MODE;
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Return the trading limits for a given exchange id. Each limit is an object with the following fields:
|
|
266
|
+
* asset: the address of the asset with the limit
|
|
267
|
+
* maxIn: the maximum amount of the asset that can be sold
|
|
268
|
+
* maxOut: the maximum amount of the asset that can be bought
|
|
269
|
+
* until: the timestamp until which the limit is valid
|
|
270
|
+
* @param exchangeId the id of the exchange
|
|
271
|
+
* @returns the list of trading limits
|
|
272
|
+
*/
|
|
273
|
+
getTradingLimits(exchangeId) {
|
|
274
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
275
|
+
const exchange = yield this.getExchangeById(exchangeId);
|
|
276
|
+
const broker = Broker__factory.connect(this.broker.address, this.signerOrProvider);
|
|
277
|
+
const assetWithLimit = exchange.assets[0]; // currently limits are configured only on asset0
|
|
278
|
+
return getLimits(broker, exchangeId, assetWithLimit);
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Returns the trading limits configuration for a given exchange id
|
|
283
|
+
* @param exchangeId the id of the exchange
|
|
284
|
+
* @returns the trading limits configuration
|
|
285
|
+
*/
|
|
286
|
+
getTradingLimitConfig(exchangeId) {
|
|
287
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
288
|
+
const exchange = yield this.getExchangeById(exchangeId);
|
|
289
|
+
const broker = Broker__factory.connect(this.broker.address, this.signerOrProvider);
|
|
290
|
+
const assetWithLimit = exchange.assets[0]; // currently limits are configured only on asset0
|
|
291
|
+
return getLimitsConfig(broker, exchangeId, assetWithLimit);
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Returns the trading limits state for a given exchange id
|
|
296
|
+
* @param exchangeId the id of the exchange
|
|
297
|
+
* @returns the trading limits state
|
|
298
|
+
*/
|
|
299
|
+
getTradingLimitState(exchangeId) {
|
|
300
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
301
|
+
const exchange = yield this.getExchangeById(exchangeId);
|
|
302
|
+
const broker = Broker__factory.connect(this.broker.address, this.signerOrProvider);
|
|
303
|
+
const assetWithLimit = exchange.assets[0]; // currently limits are configured only on asset0
|
|
304
|
+
return getLimitsState(broker, exchangeId, assetWithLimit);
|
|
305
|
+
});
|
|
306
|
+
}
|
|
222
307
|
}
|
package/dist/esm/types.d.ts
CHANGED
|
@@ -1 +1,22 @@
|
|
|
1
1
|
export type Address = string;
|
|
2
|
+
export interface TradingLimit {
|
|
3
|
+
asset: Address;
|
|
4
|
+
maxIn: number;
|
|
5
|
+
maxOut: number;
|
|
6
|
+
until: number;
|
|
7
|
+
}
|
|
8
|
+
export interface TradingLimitsConfig {
|
|
9
|
+
timestep0: number;
|
|
10
|
+
timestep1: number;
|
|
11
|
+
limit0: number;
|
|
12
|
+
limit1: number;
|
|
13
|
+
limitGlobal: number;
|
|
14
|
+
flags: number;
|
|
15
|
+
}
|
|
16
|
+
export interface TradingLimitsState {
|
|
17
|
+
lastUpdated0: number;
|
|
18
|
+
lastUpdated1: number;
|
|
19
|
+
netflow0: number;
|
|
20
|
+
netflow1: number;
|
|
21
|
+
netflowGlobal: number;
|
|
22
|
+
}
|
package/dist/esm/utils.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BigNumberish, providers, Signer } from 'ethers';
|
|
2
2
|
import { Address } from './types';
|
|
3
3
|
/**
|
|
4
4
|
* Ensures that given signer is truly a a connected signer
|
|
@@ -30,7 +30,7 @@ export declare function getSymbolFromTokenAddress(tokenAddr: Address, signerOrPr
|
|
|
30
30
|
* @param tokenAddr the address of the erc20 token
|
|
31
31
|
* @param spender the address of the spender
|
|
32
32
|
* @param amount the amount to increase the allowance by
|
|
33
|
-
* @param
|
|
33
|
+
* @param signerOrProvider an ethers signer or provider
|
|
34
34
|
* @returns the populated TransactionRequest object
|
|
35
35
|
*/
|
|
36
|
-
export declare function increaseAllowance(tokenAddr: string, spender: string, amount:
|
|
36
|
+
export declare function increaseAllowance(tokenAddr: string, spender: string, amount: BigNumberish, signerOrProvider: Signer | providers.Provider): Promise<providers.TransactionRequest>;
|
package/dist/esm/utils.js
CHANGED
|
@@ -74,15 +74,17 @@ export function getSymbolFromTokenAddress(tokenAddr, signerOrProvider) {
|
|
|
74
74
|
* @param tokenAddr the address of the erc20 token
|
|
75
75
|
* @param spender the address of the spender
|
|
76
76
|
* @param amount the amount to increase the allowance by
|
|
77
|
-
* @param
|
|
77
|
+
* @param signerOrProvider an ethers signer or provider
|
|
78
78
|
* @returns the populated TransactionRequest object
|
|
79
79
|
*/
|
|
80
|
-
export function increaseAllowance(tokenAddr, spender, amount,
|
|
80
|
+
export function increaseAllowance(tokenAddr, spender, amount, signerOrProvider) {
|
|
81
81
|
return __awaiter(this, void 0, void 0, function* () {
|
|
82
82
|
const abi = [
|
|
83
83
|
'function increaseAllowance(address spender, uint256 value) external returns (bool)',
|
|
84
84
|
];
|
|
85
|
-
|
|
85
|
+
// TODO, not all ERC-20 contracts support increaseAllowance
|
|
86
|
+
// Add a check for that here
|
|
87
|
+
const contract = new Contract(tokenAddr, abi, signerOrProvider);
|
|
86
88
|
return yield contract.populateTransaction.increaseAllowance(spender, amount);
|
|
87
89
|
});
|
|
88
90
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mento-protocol/mento-sdk",
|
|
3
3
|
"description": "Official SDK for interacting with the Mento Protocol",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.5",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Mento Labs",
|
|
7
7
|
"keywords": [
|
|
@@ -77,10 +77,10 @@
|
|
|
77
77
|
"typescript": "^4.9.5"
|
|
78
78
|
},
|
|
79
79
|
"dependencies": {
|
|
80
|
-
"@mento-protocol/mento-core-ts": "^0.1.
|
|
80
|
+
"@mento-protocol/mento-core-ts": "^0.1.1"
|
|
81
81
|
},
|
|
82
82
|
"peerDependencies": {
|
|
83
|
-
"ethers": "^5.7
|
|
83
|
+
"ethers": "^5.7"
|
|
84
84
|
},
|
|
85
85
|
"packageManager": "yarn@3.3.1"
|
|
86
86
|
}
|