Added getSwapInfo

This commit is contained in:
Aleksandr Kraiz
2022-08-25 11:00:28 +04:00
parent 2a311c281e
commit d2a6c9c127
4 changed files with 190 additions and 28 deletions

View File

@@ -103,33 +103,57 @@ orionUnit.exchange.deposit({
});
```
### Get swap market fee info
### Get swap info
```ts
orionUnit.exchange
.getSwapMarketFeeInfo({
type: "exactSpend",
assetIn: "ORN",
assetOut: "USDT",
feeAsset: "ORN",
amount: 23.89045345,
options: {
// Optional
poolOnly: false,
},
})
.then(console.log);
const { swapInfo, fee } = await orionUnit.exchange.getSwapInfo({
type: "exactSpend",
assetIn: "ORN",
assetOut: "USDT",
feeAsset: "ORN",
amount: 23.89045345,
options: {
// Optional
instantSettlement: true,
poolOnly: false,
},
});
console.log(swapInfo);
console.log(fee);
// {
// feeAsset: 'BNB',
// feeAssetAddress: '0x0000000000000000000000000000000000000000',
// feeAmount: '0.006'
// }
// {
// feeAsset: 'ORN',
// feeAssetAddress: '0xf223eca06261145b3287a0fefd8cfad371c7eb34',
// feeAmount: '2.5910754708713146879833915507960091181362655'
// swapInfo: {
// id: 'e5d50b8e-ca82-4826-b454-3fa12b693c11',
// amountIn: 20,
// amountOut: 25.68,
// assetIn: 'ORN',
// assetOut: 'USDT',
// path: [ 'ORN', 'USDT' ],
// isThroughPoolOptimal: false,
// executionInfo: '...',
// orderInfo: {
// assetPair: 'ORN-USDT',
// side: 'SELL',
// amount: 20,
// safePrice: 1.284
// },
// exchanges: [ 'BINANCE' ],
// price: 1.284,
// minAmountOut: 12,
// minAmountIn: 9.4,
// marketPrice: 1.284,
// availableAmountOut: null,
// availableAmountIn: 20,
// marketAmountOut: 25.68,
// marketAmountIn: null,
// type: 'exactSpend'
// },
// fee: {
// assetName: 'ORN',
// assetAddress: '0xf223eca06261145b3287a0fefd8cfad371c7eb34',
// amount: '1.0247136357221697138126003277499197658871168'
// }
// }
```

View File

@@ -1,6 +1,6 @@
{
"name": "@orionprotocol/sdk",
"version": "0.14.2",
"version": "0.15.0",
"description": "Orion Protocol SDK",
"main": "./lib/esm/index.js",
"module": "./lib/esm/index.js",

View File

@@ -0,0 +1,138 @@
import BigNumber from 'bignumber.js';
import { ethers } from 'ethers';
import { utils } from '../..';
import { NATIVE_CURRENCY_PRECISION, SWAP_THROUGH_ORION_POOL_GAS_LIMIT } from '../../constants';
import { OrionAggregator } from '../../services/OrionAggregator';
import { OrionBlockchain } from '../../services/OrionBlockchain';
import simpleFetch from '../../simpleFetch';
import getNativeCryptocurrency from '../../utils/getNativeCryptocurrency';
export type GetSwapInfoParams = {
type: 'exactSpend' | 'exactReceive',
assetIn: string,
assetOut: string,
amount: BigNumber.Value,
feeAsset: string,
orionBlockchain: OrionBlockchain,
orionAggregator: OrionAggregator
options?: {
instantSettlement?: boolean,
poolOnly?: boolean,
}
}
export default async function getSwapInfo({
type,
assetIn,
assetOut,
amount,
feeAsset,
orionBlockchain,
orionAggregator,
options,
}: GetSwapInfoParams) {
if (amount === '') throw new Error('Amount can not be empty');
if (assetIn === '') throw new Error('AssetIn can not be empty');
if (assetOut === '') throw new Error('AssetOut can not be empty');
if (feeAsset === '') throw new Error('Fee asset can not be empty');
const amountBN = new BigNumber(amount);
if (amountBN.isNaN()) throw new Error(`Amount '${amount.toString()}' is not a number`);
if (amountBN.lte(0)) throw new Error(`Amount '${amount.toString()}' should be greater than 0`);
const {
assetToAddress,
} = await simpleFetch(orionBlockchain.getInfo)();
const nativeCryptocurrency = getNativeCryptocurrency(assetToAddress);
const feeAssets = await simpleFetch(orionBlockchain.getTokensFee)();
const pricesInOrn = await simpleFetch(orionBlockchain.getPrices)();
const gasPriceWei = await simpleFetch(orionBlockchain.getGasPriceWei)();
const gasPriceGwei = ethers.utils.formatUnits(gasPriceWei, 'gwei').toString();
const assetInAddress = assetToAddress[assetIn];
if (!assetInAddress) throw new Error(`Asset '${assetIn}' not found`);
const feeAssetAddress = assetToAddress[feeAsset];
if (!feeAssetAddress) throw new Error(`Fee asset '${feeAsset}' not found. Available assets: ${Object.keys(feeAssets).join(', ')}`);
const swapInfo = await simpleFetch(orionAggregator.getSwapInfo)(
type,
assetIn,
assetOut,
amount.toString(),
options?.instantSettlement,
options?.poolOnly ? 'pools' : undefined,
);
if (swapInfo.orderInfo !== null && options?.poolOnly === true && options.poolOnly !== swapInfo.isThroughPoolOptimal) {
throw new Error(`Unexpected Orion Aggregator response. Please, contact support. Report swap request id: ${swapInfo.id}`);
}
// if (swapInfo.type === 'exactReceive' && amountBN.lt(swapInfo.minAmountOut)) {
// throw new Error(`Amount is too low. Min amountOut is ${swapInfo.minAmountOut} ${assetOut}`);
// }
// if (swapInfo.type === 'exactSpend' && amountBN.lt(swapInfo.minAmountIn)) {
// throw new Error(`Amount is too low. Min amountIn is ${swapInfo.minAmountIn} ${assetIn}`);
// }
// if (swapInfo.orderInfo === null) throw new Error(swapInfo.executionInfo);
let isThroughPoolOptimal: boolean;
if (options?.poolOnly) isThroughPoolOptimal = true;
else isThroughPoolOptimal = swapInfo.isThroughPoolOptimal;
if (isThroughPoolOptimal) {
const transactionCost = ethers.BigNumber.from(SWAP_THROUGH_ORION_POOL_GAS_LIMIT).mul(gasPriceWei);
const denormalizedTransactionCost = utils.denormalizeNumber(transactionCost, NATIVE_CURRENCY_PRECISION);
return {
swapInfo,
fee: {
assetName: nativeCryptocurrency,
assetAddress: ethers.constants.AddressZero,
amount: denormalizedTransactionCost.toString(),
},
};
}
let feeAmount: string | undefined;
if (swapInfo.orderInfo) {
const [baseAssetName] = swapInfo.orderInfo.assetPair.split('-');
if (baseAssetName === undefined) throw new Error('Base asset name is undefined');
const baseAssetAddress = assetToAddress[baseAssetName];
if (!baseAssetAddress) throw new Error(`No asset address for ${baseAssetName}`);
// Fee calculation
const baseAssetPriceInOrn = pricesInOrn?.[baseAssetAddress];
if (!baseAssetPriceInOrn) throw new Error(`Base asset price ${baseAssetName} in ORN not found`);
const baseCurrencyPriceInOrn = pricesInOrn[ethers.constants.AddressZero];
if (!baseCurrencyPriceInOrn) throw new Error('Base currency price in ORN not found');
const feeAssetPriceInOrn = pricesInOrn[feeAssetAddress];
if (!feeAssetPriceInOrn) throw new Error(`Fee asset price ${feeAsset} in ORN not found`);
const feePercent = feeAssets?.[feeAsset];
if (!feePercent) throw new Error(`Fee asset ${feeAsset} not available`);
const { totalFeeInFeeAsset } = utils.calculateFeeInFeeAsset(
swapInfo.orderInfo.amount,
feeAssetPriceInOrn,
baseAssetPriceInOrn,
baseCurrencyPriceInOrn,
gasPriceGwei,
feePercent,
);
feeAmount = totalFeeInFeeAsset;
}
return {
swapInfo,
fee: {
assetName: feeAsset,
assetAddress: feeAssetAddress,
amount: feeAmount,
},
};
}

View File

@@ -1,13 +1,13 @@
import OrionUnit from '..';
import deposit, { DepositParams } from './deposit';
import getSwapMarketFeeInfo, { GetSwapMarketInfoParams } from './getSwapMarketFeeInfo';
import getSwapInfo, { GetSwapInfoParams } from './getSwapInfo';
import swapMarket, { SwapMarketParams } from './swapMarket';
import withdraw, { WithdrawParams } from './withdraw';
type PureSwapMarketParams= Omit<SwapMarketParams, 'orionUnit'>
type PureDepositParams = Omit<DepositParams, 'orionUnit'>
type PureWithdrawParams = Omit<WithdrawParams, 'orionUnit'>
type PureGetSwapMarketInfoParams= Omit<GetSwapMarketInfoParams, 'orionBlockchain' | 'orionAggregator'>
type PureGetSwapMarketInfoParams= Omit<GetSwapInfoParams, 'orionBlockchain' | 'orionAggregator'>
export default class Exchange {
private readonly orionUnit: OrionUnit;
@@ -23,8 +23,8 @@ export default class Exchange {
});
}
public getSwapMarketFeeInfo(params: PureGetSwapMarketInfoParams) {
return getSwapMarketFeeInfo({
public getSwapInfo(params: PureGetSwapMarketInfoParams) {
return getSwapInfo({
orionAggregator: this.orionUnit.orionAggregator,
orionBlockchain: this.orionUnit.orionBlockchain,
...params,