@astonic-io/astonic-sdk
Version:
Official SDK for interacting with the Astonic Protocol
651 lines (650 loc) • 31.8 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Astonic = void 0;
const astonic_bindings_ts_1 = require("@astonic-io/astonic-bindings-ts");
const ethers_1 = require("ethers");
const limits_1 = require("./limits");
const utils_1 = require("./utils");
const assert_1 = require("assert");
const astonic_router_ts_1 = require("@astonic-io/astonic-router-ts");
const addresses_1 = require("./constants/addresses");
const tradablePairs_1 = require("./constants/tradablePairs");
class Astonic {
/**
* This constructor is private, use the static create or createWithParams methods
* to create a new Astonic instance
* @param signerOrProvider an ethers provider or connected signer
* @param brokerAddress the address of the broker contract
* @param exchanges exchange data for the broker
*/
constructor(signerOrProvider, brokerAddress, routerAddress, exchanges) {
this.signerOrProvider = signerOrProvider;
this.broker = astonic_bindings_ts_1.IBroker0828__factory.connect(brokerAddress, signerOrProvider);
this.router = astonic_router_ts_1.IAstonicRouter__factory.connect(routerAddress, signerOrProvider);
this.exchanges = exchanges || [];
}
/**
* Creates a new Astonic object instance.
* When constructed with only a Provider only read-only operations are supported
* @param signerOrProvider an ethers signer or provider. A signer is required to execute swaps
* @returns a new Astonic object instance
*/
static create(signerOrProvider) {
return __awaiter(this, void 0, void 0, function* () {
(0, utils_1.validateSignerOrProvider)(signerOrProvider);
return new Astonic(signerOrProvider, yield (0, utils_1.getBrokerAddressFromRegistry)(signerOrProvider), yield (0, addresses_1.getAddress)('AstonicRouter', yield (0, utils_1.getChainId)(signerOrProvider)));
});
}
/**
* Create a new Astonic object instance given a broker address and optional exchanges data
* When constructed with a Provider, only read-only operations are supported
* @param signerOrProvider an ethers signer or provider. A signer is required to execute swaps
* @param brokerAddr the address of the broker contract
* @param exchanges the exchanges data for the broker
* @returns a new Astonic object instance
*/
static createWithParams(signerOrProvider, brokerAddr, routerAddr, exchanges) {
(0, utils_1.validateSignerOrProvider)(signerOrProvider);
return new Astonic(signerOrProvider, brokerAddr, routerAddr, exchanges);
}
/**
* Returns a new Astonic instance connected to the given signer
* @param signer an ethers signer
* @returns new Astonic object instance
*/
connectSigner(signer) {
(0, utils_1.validateSigner)(signer);
return new Astonic(signer, this.broker.address, this.router.address, this.exchanges);
}
/**
* Get tradable pairs for backwards compatibility
* @returns an array of Asset pairs
*/
getTradablePairs(options) {
var _a;
return __awaiter(this, void 0, void 0, function* () {
return (yield this.getTradablePairsWithPath({ cached: (_a = options === null || options === void 0 ? void 0 : options.cached) !== null && _a !== void 0 ? _a : true })).map((pair) => pair.assets);
});
}
/**
* Returns a list of all tradable pairs on Astonic via direct exchanges.
* Each pair is represented using the TradablePair interface, with its id
* (a concatenation of the two asset symbols in alphabetical order),
* the two Asset objects, and a path (an array with a single direct exchange hop).
* @returns An array of direct TradablePair objects.
*/
getDirectPairs() {
return __awaiter(this, void 0, void 0, function* () {
const exchanges = yield this.getExchanges();
// Map from pair id (symbol-symbol) to its TradablePair
const directPairsMap = new Map();
for (const exchange of exchanges) {
const [token0, token1] = exchange.assets;
const [symbol0, symbol1] = yield Promise.all([
(0, utils_1.getSymbolFromTokenAddress)(token0, this.signerOrProvider),
(0, utils_1.getSymbolFromTokenAddress)(token1, this.signerOrProvider),
]);
// Determine canonical order by symbol
let assets;
let pairId;
if (symbol0 <= symbol1) {
assets = [
{ address: token0, symbol: symbol0 },
{ address: token1, symbol: symbol1 },
];
pairId = `${symbol0}-${symbol1}`;
}
else {
assets = [
{ address: token1, symbol: symbol1 },
{ address: token0, symbol: symbol0 },
];
pairId = `${symbol1}-${symbol0}`;
}
const pathEntry = {
providerAddr: exchange.providerAddr,
id: exchange.id,
assets: exchange.assets,
};
if (directPairsMap.has(pairId)) {
directPairsMap.get(pairId).path.push(pathEntry);
}
else {
directPairsMap.set(pairId, { id: pairId, assets, path: [pathEntry] });
}
}
return Array.from(directPairsMap.values());
});
}
/**
* Returns a list of all tradable pairs on Astonic, including those achievable
* via two-hop routes. For two-hop pairs, the path will contain two exchange hops.
* Each TradablePair contains an id (the concatenation of the two asset symbols in alphabetical order),
* the two Asset objects, and an array of exchange details for each hop.
* @returns An array of TradablePair objects representing available trade routes.
*/
getTradablePairsWithPath(options) {
return __awaiter(this, void 0, void 0, function* () {
// Get tradable pairs from cache if available.
if (options === null || options === void 0 ? void 0 : options.cached) {
const value = (0, tradablePairs_1.getCachedTradablePairs)(yield (0, utils_1.getChainId)(this.signerOrProvider));
if (value) {
return value;
}
}
// Retrieve direct pairs first.
const directPairs = yield this.getDirectPairs();
// Build helper maps:
// assetMap: maps token address to its Asset details.
const assetMap = new Map();
// directPathMap: maps a sorted pair of token addresses (by address) to a direct exchange hop.
const directPathMap = new Map();
// graph: maps a token address to the set of addresses it connects to directly.
const graph = new Map();
for (const pair of directPairs) {
const [assetA, assetB] = pair.assets;
assetMap.set(assetA.address, assetA);
assetMap.set(assetB.address, assetB);
const sortedAddresses = [assetA.address, assetB.address].sort().join('-');
if (!directPathMap.has(sortedAddresses)) {
// Use the first available direct hop for the connectivity graph.
directPathMap.set(sortedAddresses, pair.path[0]);
}
if (!graph.has(assetA.address))
graph.set(assetA.address, new Set());
if (!graph.has(assetB.address))
graph.set(assetB.address, new Set());
graph.get(assetA.address).add(assetB.address);
graph.get(assetB.address).add(assetA.address);
}
// Initialize tradablePairsMap with direct pairs keyed by their id (symbol-symbol).
const tradablePairsMap = new Map();
for (const pair of directPairs) {
tradablePairsMap.set(pair.id, pair);
}
// Generate two-hop pairs using the connectivity graph.
// For each potential route: start -> intermediate -> end, add a two-hop pair
// only if no direct route (i.e. same symbol pair) exists.
for (const [start, neighbors] of graph.entries()) {
for (const intermediate of neighbors) {
const secondHopNeighbors = graph.get(intermediate);
if (!secondHopNeighbors)
continue;
for (const end of secondHopNeighbors) {
if (end === start)
continue; // Avoid self-loop.
const assetStart = assetMap.get(start);
const assetEnd = assetMap.get(end);
if (!assetStart || !assetEnd)
continue;
// Determine canonical pair id based on asset symbols.
const sortedSymbols = [assetStart.symbol, assetEnd.symbol].sort();
const pairId = `${sortedSymbols[0]}-${sortedSymbols[1]}`;
if (tradablePairsMap.has(pairId))
continue; // Skip if a direct pair exists.
// Retrieve the direct hops for the two segments.
const hop1Key = [start, intermediate].sort().join('-');
const hop2Key = [intermediate, end].sort().join('-');
const hop1 = directPathMap.get(hop1Key);
const hop2 = directPathMap.get(hop2Key);
if (!hop1 || !hop2)
continue;
let assets;
if (assetStart.symbol <= assetEnd.symbol) {
assets = [assetStart, assetEnd];
}
else {
assets = [assetEnd, assetStart];
}
tradablePairsMap.set(pairId, {
id: pairId,
assets,
path: [hop1, hop2],
});
}
}
}
return Array.from(tradablePairsMap.values());
});
}
/**
* Returns the amount of tokenIn to be sold to buy amountOut of tokenOut.
* If the provided tradablePair has a single (direct) pricing path, then direct pricing is used.
* Otherwise, routed pricing via the AstonicRouter is applied.
* @param tokenIn the token to be sold
* @param tokenOut the token to be bought
* @param amountOut the desired amount of tokenOut to be obtained
* @param tradablePair the TradablePair object containing the pricing path information
* @returns the amount of tokenIn to be sold
*/
getAmountIn(tokenIn, tokenOut, amountOut, tradablePair) {
return __awaiter(this, void 0, void 0, function* () {
if (!tradablePair) {
tradablePair = yield this.findPairForTokens(tokenIn, tokenOut);
}
if (tradablePair.path.length === 1) {
return this.getAmountInDirect(tokenIn, tokenOut, amountOut, tradablePair);
}
else {
return this.getAmountInRouted(tokenIn, tokenOut, amountOut, tradablePair);
}
});
}
/**
* Returns the amount of tokenOut to be bought by selling amountIn of tokenIn.
* If the provided tradablePair has a single (direct) pricing path, then direct pricing is used.
* Otherwise, routed pricing via the AstonicRouter is applied.
* @param tokenIn the token to be sold
* @param tokenOut the token to be bought
* @param amountIn the amount of tokenIn to be sold
* @param tradablePair the TradablePair object containing the pricing path information
* @returns the amount of tokenOut to be bought
*/
getAmountOut(tokenIn, tokenOut, amountIn, tradablePair) {
return __awaiter(this, void 0, void 0, function* () {
if (!tradablePair) {
tradablePair = yield this.findPairForTokens(tokenIn, tokenOut);
}
if (tradablePair.path.length === 1) {
return this.getAmountOutDirect(tokenIn, tokenOut, amountIn, tradablePair);
}
else {
return this.getAmountOutRouted(tokenIn, tokenOut, amountIn, tradablePair);
}
});
}
/**
* Internal method for direct pricing: retrieves the exchange for the given tokens
* and returns the amountIn using the broker.
*/
getAmountInDirect(tokenIn, tokenOut, amountOut, tradablePair) {
return __awaiter(this, void 0, void 0, function* () {
return this.broker.getAmountIn(tradablePair.path[0].providerAddr, tradablePair.path[0].id, tokenIn, tokenOut, amountOut);
});
}
/**
* Internal method for direct pricing: retrieves the exchange for the given tokens
* and returns the amountOut using the broker.
*/
getAmountOutDirect(tokenIn, tokenOut, amountIn, tradablePair) {
return __awaiter(this, void 0, void 0, function* () {
return this.broker.getAmountOut(tradablePair.path[0].providerAddr, tradablePair.path[0].id, tokenIn, tokenOut, amountIn);
});
}
/**
* Internal method for routed pricing: uses the AstonicRouter to determine the required tokenIn
* for obtaining amountOut through a multi-hop route specified in tradablePair.path.
*/
getAmountInRouted(tokenIn, tokenOut, amountOut, tradablePair) {
return __awaiter(this, void 0, void 0, function* () {
const steps = this.buildSteps(tokenIn, tokenOut, tradablePair);
return this.router.getAmountIn(amountOut, steps);
});
}
/**
* Internal method for routed pricing: uses the AstonicRouter to determine the amountOut
* obtainable by selling amountIn through a multi-hop route specified in tradablePair.path.
*/
getAmountOutRouted(tokenIn, tokenOut, amountIn, tradablePair) {
return __awaiter(this, void 0, void 0, function* () {
const steps = this.buildSteps(tokenIn, tokenOut, tradablePair);
return this.router.getAmountOut(amountIn, steps);
});
}
/**
* Increases the broker's trading allowance for the given token
* @param token the token to increase the allowance for
* @param amount the amount to increase the allowance by
* @returns the populated TransactionRequest object
*/
increaseTradingAllowance(tokenIn, amount, tradablePair) {
return __awaiter(this, void 0, void 0, function* () {
const spender = !tradablePair || (tradablePair === null || tradablePair === void 0 ? void 0 : tradablePair.path.length) == 1
? this.broker.address
: this.router.address;
const tx = yield (0, utils_1.increaseAllowance)(tokenIn, spender, amount, this.signerOrProvider);
if (ethers_1.Signer.isSigner(this.signerOrProvider)) {
// The contract call doesn't populate all of the signer fields, so we need an extra call for the signer
return this.signerOrProvider.populateTransaction(tx);
}
else {
return tx;
}
});
}
/**
* Increases the broker's trading allowance for the given token
* @param token the token to increase the allowance for
* @param amount the amount to increase the allowance by
* @returns the populated TransactionRequest object
*/
wrapToken(tokenIn, amount) {
return __awaiter(this, void 0, void 0, function* () {
const tx = yield (0, utils_1.wrap)(tokenIn, amount, this.signerOrProvider);
if (ethers_1.Signer.isSigner(this.signerOrProvider)) {
// The contract call doesn't populate all of the signer fields, so we need an extra call for the signer
return this.signerOrProvider.populateTransaction(tx);
}
else {
return tx;
}
});
}
/**
* Increases the broker's trading allowance for the given token
* @param token the token to increase the allowance for
* @param amount the amount to increase the allowance by
* @returns the populated TransactionRequest object
*/
unwrapToken(tokenIn, amount) {
return __awaiter(this, void 0, void 0, function* () {
const tx = yield (0, utils_1.unwrap)(tokenIn, amount, this.signerOrProvider);
if (ethers_1.Signer.isSigner(this.signerOrProvider)) {
// The contract call doesn't populate all of the signer fields, so we need an extra call for the signer
return this.signerOrProvider.populateTransaction(tx);
}
else {
return tx;
}
});
}
/**
* Returns a token swap populated tx object with a fixed amount of tokenIn and a minimum amount of tokenOut.
* If the tradablePair contains a single-hop route, a direct swap is executed using swapExactTokensForTokens on the broker.
* Otherwise, a routed swap is executed via the router.
* @param tokenIn the token to be sold
* @param tokenOut the token to be bought
* @param amountIn the amount of tokenIn to be sold
* @param amountOutMin the minimum amount of tokenOut to be bought
* @param tradablePair the tradable pair details to determine routing
* @returns the populated TransactionRequest object
*/
swapIn(tokenIn, tokenOut, amountIn, amountOutMin, tradablePair) {
return __awaiter(this, void 0, void 0, function* () {
if (!tradablePair) {
tradablePair = yield this.findPairForTokens(tokenIn, tokenOut);
}
if (tradablePair.path.length === 1) {
return this.swapInDirect(tokenIn, tokenOut, amountIn, amountOutMin);
}
else {
return this.swapInRouted(tokenIn, tokenOut, amountIn, amountOutMin, tradablePair);
}
});
}
swapInDirect(tokenIn, tokenOut, amountIn, amountOutMin) {
return __awaiter(this, void 0, void 0, function* () {
const exchange = yield this.getExchangeForTokens(tokenIn, tokenOut);
const tx = yield this.broker.populateTransaction.swapIn(exchange.providerAddr, exchange.id, tokenIn, tokenOut, amountIn, amountOutMin);
return ethers_1.Signer.isSigner(this.signerOrProvider)
? this.signerOrProvider.populateTransaction(tx)
: tx;
});
}
swapInRouted(tokenIn, tokenOut, amountIn, amountOutMin, tradablePair) {
return __awaiter(this, void 0, void 0, function* () {
const steps = this.buildSteps(tokenIn, tokenOut, tradablePair);
const tx = yield this.router.populateTransaction.swapExactTokensForTokens(amountIn, amountOutMin, steps);
return ethers_1.Signer.isSigner(this.signerOrProvider)
? this.signerOrProvider.populateTransaction(tx)
: tx;
});
}
/**
* Returns a token swap populated tx object with a maximum amount of tokenIn and a fixed amount of tokenOut.
* If the tradablePair contains a single-hop route, a direct swap is executed using swapTokensForExactTokens on the broker.
* Otherwise, a routed swap is executed via the router.
* @param tokenIn the token to be sold
* @param tokenOut the token to be bought
* @param amountOut the amount of tokenOut to be bought
* @param amountInMax the maximum amount of tokenIn to be sold
* @returns the populated TransactionRequest object
*/
swapOut(tokenIn, tokenOut, amountOut, amountInMax, tradablePair) {
return __awaiter(this, void 0, void 0, function* () {
if (!tradablePair) {
tradablePair = yield this.findPairForTokens(tokenIn, tokenOut);
}
if (tradablePair.path.length === 1) {
return this.swapOutDirect(tokenIn, tokenOut, amountOut, amountInMax);
}
else {
return this.swapOutRouted(tokenIn, tokenOut, amountOut, amountInMax, tradablePair);
}
});
}
swapOutDirect(tokenIn, tokenOut, amountOut, amountInMax) {
return __awaiter(this, void 0, void 0, function* () {
const exchange = yield this.getExchangeForTokens(tokenIn, tokenOut);
const tx = yield this.broker.populateTransaction.swapOut(exchange.providerAddr, exchange.id, tokenIn, tokenOut, amountOut, amountInMax);
return ethers_1.Signer.isSigner(this.signerOrProvider)
? this.signerOrProvider.populateTransaction(tx)
: tx;
});
}
swapOutRouted(tokenIn, tokenOut, amountOut, amountInMax, tradablePair) {
return __awaiter(this, void 0, void 0, function* () {
const steps = this.buildSteps(tokenIn, tokenOut, tradablePair);
const tx = yield this.router.populateTransaction.swapTokensForExactTokens(amountOut, amountInMax, steps);
return ethers_1.Signer.isSigner(this.signerOrProvider)
? this.signerOrProvider.populateTransaction(tx)
: tx;
});
}
/**
* Helper method to build the steps for a routed swap, ensuring proper token ordering
* through the path segments
*/
buildSteps(tokenIn, tokenOut, tradablePair) {
let path = [...tradablePair.path];
if (path[0].assets.includes(tokenOut)) {
path = path.reverse();
}
return path.map((step, idx) => {
const isFirstStep = idx === 0;
const isLastStep = idx === tradablePair.path.length - 1;
const prevStep = idx > 0 ? tradablePair.path[idx - 1] : null;
// For first step, ensure assetIn is tokenIn
// For middle steps, ensure assetIn matches previous step's assetOut
// For last step, ensure assetOut is tokenOut
let [assetIn, assetOut] = step.assets;
if (isFirstStep && assetIn !== tokenIn) {
;
[assetIn, assetOut] = [assetOut, assetIn];
}
else if (!isFirstStep &&
!isLastStep &&
assetIn !== prevStep.assets[1]) {
;
[assetIn, assetOut] = [assetOut, assetIn];
}
else if (isLastStep && assetOut !== tokenOut) {
;
[assetIn, assetOut] = [assetOut, assetIn];
}
return {
exchangeProvider: step.providerAddr,
exchangeId: step.id,
assetIn,
assetOut,
};
});
}
/**
* Returns the astonic instance's broker contract
* @returns broker contract
*/
getBroker() {
return this.broker;
}
/**
* Finds a tradable pair for the given input and output tokens
* @param tokenIn the input token address
* @param tokenOut the output token address
* @returns the tradable pair containing the path between the tokens
* @throws if no path is found between the tokens
*/
findPairForTokens(tokenIn, tokenOut) {
return __awaiter(this, void 0, void 0, function* () {
const pair = (yield this.getTradablePairsWithPath()).find((p) =>
// Direct path
(p.path.length === 1 &&
p.path[0].assets.includes(tokenIn) &&
p.path[0].assets.includes(tokenOut)) ||
// Routed path
(p.path.length === 2 &&
((p.path[0].assets.includes(tokenIn) &&
p.path[1].assets.includes(tokenOut)) ||
(p.path[0].assets.includes(tokenOut) &&
p.path[1].assets.includes(tokenIn)))));
if (!pair) {
throw new Error(`No tradable pair found for tokens ${tokenIn} and ${tokenOut}`);
}
return pair;
});
}
/**
* Returns the list of exchanges available in Astonic (cached)
* @returns the list of exchanges
*/
getExchanges() {
return __awaiter(this, void 0, void 0, function* () {
if (this.exchanges.length > 0) {
return this.exchanges;
}
const exchangeProvidersAddresses = yield this.broker.getExchangeProviders();
const exchanges = (yield Promise.all(exchangeProvidersAddresses.map((a) => this.getExchangesForProvider(a)))).flat();
this.exchanges = exchanges;
return exchanges;
});
}
/**
* Returns the list of exchanges for a given exchange provider address
* @returns list of exchanges
*/
getExchangesForProvider(exchangeProviderAddr) {
return __awaiter(this, void 0, void 0, function* () {
const exchangeProvider = astonic_bindings_ts_1.IExchangeProvider0828__factory.connect(exchangeProviderAddr, this.signerOrProvider);
const exchangesInProvider = yield exchangeProvider.getExchanges();
return exchangesInProvider.map((e) => {
(0, assert_1.strict)(e.assets.length === 2, 'Exchange must have 2 assets');
return {
providerAddr: exchangeProviderAddr,
id: e.exchangeId,
assets: e.assets,
};
});
});
}
/**
* Returns the Astonic exchange (if any) for a given pair of tokens
* @param token0 the address of the first token
* @param token1 the address of the second token
* @returns exchange
*/
getExchangeForTokens(token0, token1) {
return __awaiter(this, void 0, void 0, function* () {
const exchanges = (yield this.getExchanges()).filter((e) => e.assets.includes(token0) && e.assets.includes(token1));
if (exchanges.length === 0) {
throw Error(`No exchange found for ${token0} and ${token1}`);
}
(0, assert_1.strict)(exchanges.length === 1, `More than one exchange found for ${token0} and ${token1}`);
return exchanges[0];
});
}
/**
* Returns the Astonic exchange for a given exchange id
* @param exchangeId the id of the exchange
* @returns the exchange with the given id
*/
getExchangeById(exchangeId) {
return __awaiter(this, void 0, void 0, function* () {
const exchanges = (yield this.getExchanges()).filter((e) => e.id === exchangeId);
if (exchanges.length === 0) {
throw Error(`No exchange found for id ${exchangeId}`);
}
(0, assert_1.strict)(exchanges.length === 1, `More than one exchange found with id ${exchangeId}`);
return exchanges[0];
});
}
/**
* Returns whether trading is enabled in the given mode for a given exchange id
* @param exchangeId the id of the exchange
* @param mode the trading mode
* @returns true if trading is enabled in the given mode, false otherwise
*/
isTradingEnabled(exchangeId) {
return __awaiter(this, void 0, void 0, function* () {
const exchange = yield this.getExchangeById(exchangeId);
const biPoolManager = astonic_bindings_ts_1.BiPoolManager__factory.connect(exchange.providerAddr, this.signerOrProvider);
const [breakerBoxAddr, exchangeConfig] = yield Promise.all([
biPoolManager.breakerBox(),
biPoolManager.getPoolExchange(exchangeId),
]);
const breakerBox = astonic_bindings_ts_1.IBreakerBox0828__factory.connect(breakerBoxAddr, this.signerOrProvider);
const currentMode = yield breakerBox.getRateFeedTradingMode(exchangeConfig.config.referenceRateFeedID);
const BI_DIRECTIONAL_TRADING_MODE = 0;
return currentMode == BI_DIRECTIONAL_TRADING_MODE;
});
}
/**
* Return the trading limits for a given exchange id. Each limit is an object with the following fields:
* asset: the address of the asset with the limit
* maxIn: the maximum amount of the asset that can be sold
* maxOut: the maximum amount of the asset that can be bought
* until: the timestamp until which the limit is valid
* @param exchangeId the id of the exchange
* @returns the list of trading limits
*/
getTradingLimits(exchangeId) {
return __awaiter(this, void 0, void 0, function* () {
const exchange = yield this.getExchangeById(exchangeId);
const broker = astonic_bindings_ts_1.Broker__factory.connect(this.broker.address, this.signerOrProvider);
const asset0Limits = yield (0, limits_1.getLimits)(broker, exchangeId, exchange.assets[0]);
const asset1Limits = yield (0, limits_1.getLimits)(broker, exchangeId, exchange.assets[1]);
return asset0Limits.concat(asset1Limits);
});
}
/**
* Returns the trading limits configurations for a given exchange id
* @param exchangeId the id of the exchange
* @returns the trading limits configuration
*/
getTradingLimitConfig(exchangeId) {
return __awaiter(this, void 0, void 0, function* () {
const exchange = yield this.getExchangeById(exchangeId);
const broker = astonic_bindings_ts_1.Broker__factory.connect(this.broker.address, this.signerOrProvider);
const cfgs = [];
for (const asset of exchange.assets) {
const limitCfg = yield (0, limits_1.getLimitsConfig)(broker, exchangeId, asset);
const isLimitConfigured = limitCfg.flags > 0;
if (isLimitConfigured) {
cfgs.push(limitCfg);
}
}
return cfgs;
});
}
/**
* Returns the trading limits state for a given exchange id
* @param exchangeId the id of the exchange
* @returns the trading limits state
*/
getTradingLimitState(exchangeId) {
return __awaiter(this, void 0, void 0, function* () {
const broker = astonic_bindings_ts_1.Broker__factory.connect(this.broker.address, this.signerOrProvider);
const configuredLimitCfgs = yield this.getTradingLimitConfig(exchangeId);
return yield Promise.all(configuredLimitCfgs.map((cfg) => __awaiter(this, void 0, void 0, function* () { return yield (0, limits_1.getLimitsState)(broker, exchangeId, cfg.asset); })));
});
}
}
exports.Astonic = Astonic;