> giveCoinFullInfo = await this.sdk.getCoin(this.giveCoin.toLowerCase())
> giveAmount = Кол-во монет, которые отдают
> getCoinFullInfo = await this.sdk.getCoin(this.getCoin.toLowerCase())
```ts
estimated = sell(this.giveCoinFullInfo, this.giveAmount, this.getCoinFullInfo)
```
> (process.env.baseCoin = 'DEL', если testnet, то 'tDEL')
# Функция estimate (используется на странице)
```ts
public estimate (field) : void {
let estimated = { success: false, value: '0' } as IEstimated
if (field === 'giveCoin' || field === 'sellAll') {
if (field !== 'sellAll') {
this.mode = 'sell'
}
if (this.getCoinFullInfo && this.giveCoinFullInfo && this.giveAmount && this.getCoin && this.giveCoin) {
estimated = sell(this.giveCoinFullInfo, this.giveAmount, this.getCoinFullInfo)
// @ts-ignore
this.getAmount = estimated.success ? this.DecimalNumber(estimated.value).toFixed(18).replace(/^0+(?!\.)|(?:\.|(\..*?))0+$/gm, '$1') : ''
} else if (!this.giveAmount) {
this.getAmount = ''
}
// @ts-ignore
this.estimatedGet = estimated
} else if (field === 'getCoin') {
this.mode = 'buy'
if (this.getCoinFullInfo && this.giveCoinFullInfo && this.getAmount && this.getCoin && this.giveCoin) {
estimated = buy(this.getCoinFullInfo, this.getAmount, this.giveCoinFullInfo)
// @ts-ignore
this.giveAmount = estimated.success ? this.DecimalNumber(estimated.value).toFixed(18).replace(/^0+(?!\.)|(?:\.|(\..*?))0+$/gm, '$1') : ''
} else if (!this.getAmount) {
this.giveAmount = ''
}
// @ts-ignore
this.estimatedSpend = estimated
}
}
```
# math.ts
```ts
import DecimalNumber from 'decimal.js'
interface ICoin {
crr: string;
ticker: any;
reserve: string ;
maxSupply?: string;
supply: string
}
DecimalNumber.set({ precision: 100 })
function getAmountFromSatoshi (amount: DecimalNumber.Value): string {
return new DecimalNumber(amount).times(new DecimalNumber(10).pow(-18)).toFixed()
}
function getCoinFormatted (coinData: { volume: DecimalNumber.Value; reserve: DecimalNumber.Value; crr: DecimalNumber.Value; limitVolume: DecimalNumber.Value; symbol: any; })
: ICoin {
return {
supply: getAmountFromSatoshi(coinData.volume),
reserve: getAmountFromSatoshi(coinData.reserve),
crr: new DecimalNumber(coinData.crr).div(100).toFixed(),
maxSupply: getAmountFromSatoshi(coinData.limitVolume),
ticker: coinData.symbol
}
}
/**
* Sell:
* Продажа монеты, подсчет получаемых del
*/
export const sellCoin = (coin: ICoin, coinAmount: DecimalNumber.Value): string | boolean => {
const crr = new DecimalNumber(coin.crr).times(100).toNumber()
if (new DecimalNumber(coinAmount).eq(new DecimalNumber(0))) {
return '0'
}
if (new DecimalNumber(coinAmount).eq(new DecimalNumber(coin.supply))) {
return coin.reserve
}
if (new DecimalNumber(crr).eq(new DecimalNumber(100))) {
const ret = new DecimalNumber(coin.reserve).times(new DecimalNumber(coinAmount))
return ret.div(new DecimalNumber(coin.supply)).toFixed().toString()
}
const e1 = new DecimalNumber(coinAmount).div(coin.supply)
const e2 = new DecimalNumber(1).minus(e1)
if (e2 < new DecimalNumber(0)) { return false }
const e3 = e2.pow(new DecimalNumber(100).div(crr))
const e4 = new DecimalNumber(1).minus(e3)
return e4.times(coin.reserve).toFixed()
}
/**
* Sell:
* Продажа монеты, подсчет необходимых монет
*/
export const sellCoinByDel = (coin: ICoin, delAmount: DecimalNumber.Value): string => {
// eslint-disable-next-line no-param-reassign
delAmount = Math.min(parseFloat(coin.reserve), +delAmount)
const e1 = new DecimalNumber(delAmount).div(coin.reserve)
const e2 = new DecimalNumber(1).minus(e1).pow(coin.crr)
const result = new DecimalNumber(1).minus(e2).times(coin.supply) // => coin
return result.toFixed()
}
/**
* Buy:
* Покупка монеты, подсчет получаемых монет
*/
export const buyCoin = (coin: ICoin, delAmount: string | number | DecimalNumber.Value): string => {
const e1 = new DecimalNumber(delAmount).div(coin.reserve).plus(1).pow(coin.crr)
const result = new DecimalNumber(e1).minus(1).times(coin.supply) // => coin
return result.toFixed()
}
/**
* Buy:
* Покупка монеты, подсчет необходимых del
*/
export const buyCoinByCoin = (coin: ICoin, coinAmount: number | string): string => {
const e1 = new DecimalNumber(coinAmount).div(coin.supply).plus(1)
const e2 = new DecimalNumber(1).div(coin.crr)
const result = new DecimalNumber(e1).pow(e2).minus(1).times(coin.reserve) // => del
return result.toFixed()
}
function isLessReserve (spendCoin: { reserve: DecimalNumber.Value; ticker: string; }, amount: DecimalNumber.Value): false | {key: string, coin:string} {
// console.log('spend-coin', spendCoin);
// console.log('amount', amount);
const maxDelSpend = new DecimalNumber(spendCoin.reserve).minus(1000).toFixed()
if (!amount || new DecimalNumber(amount).gt(maxDelSpend)) {
return {
key: 'reserve-limit',
coin: spendCoin.ticker.toUpperCase()
}
}
return false
}
function isMoreMaxSupply (getCoin:any, amount: DecimalNumber.Value):false | {key: string, coin:string} {
const available = new DecimalNumber(getCoin.maxSupply).minus(getCoin.supply).toFixed() // => coin
if (new DecimalNumber(amount).gt(available)) {
return {
key: 'more-limit-volume',
coin: getCoin.ticker.toUpperCase()
}
}
return false
}
// Todo
export function buy (getCoinn: any, amount: string | number, spendCoinn: any) : {success:boolean, value?:string, key?: string, coin?:string} {
const spendCoin = getCoinFormatted(spendCoinn)
const getCoin = getCoinFormatted(getCoinn)
// console.log('buy');
let estimated: any = ''
let error: false | {key: string, coin:string} = false
if (
// @ts-ignore
getCoin.ticker.toLowerCase() === process.env.baseCoin.toLowerCase()) {
estimated = sellCoinByDel(spendCoin, amount) // => coin
error = isLessReserve(spendCoin, amount)
} else if (
// @ts-ignore
spendCoin.ticker.toLowerCase() === process.env.baseCoin.toLowerCase()) {
estimated = buyCoinByCoin(getCoin, amount) // => tdel
error = isMoreMaxSupply(getCoin, amount)
} else {
const needDel = buyCoinByCoin(getCoin, amount) // => tdel
estimated = sellCoinByDel(spendCoin, needDel) // => coin
error = isMoreMaxSupply(getCoin, amount)
error = error || isLessReserve(spendCoin, needDel)
}
// error = error || isInfluentFunds(estimated, spendCoin);
if (error) {
return {
success: false,
...error
}
}
return {
success: true,
value: estimated
}
}
export function sell (spendCoinn: any, amount: string | number | DecimalNumber, getCoinn: any) : {success?:boolean, value?:string, key?: string, coin?:string} {
const spendCoin = getCoinFormatted(spendCoinn)
const getCoin = getCoinFormatted(getCoinn)
// console.log('sell');
let estimated: any = ''
let error : any = false
if (
// @ts-ignore
spendCoin.ticker.toLowerCase() === process.env.baseCoin.toLowerCase()) {
estimated = buyCoin(getCoin, amount) // => coin
error = isMoreMaxSupply(getCoin, estimated)
} else if (
// @ts-ignore
getCoin.ticker.toLowerCase() === process.env.baseCoin.toLowerCase()) {
estimated = sellCoin(spendCoin, amount)
error = isLessReserve(spendCoin, estimated)
} else {
const needDel = String(sellCoin(spendCoin, amount)) // => tdel
estimated = buyCoin(getCoin, needDel) // => coin
error = isMoreMaxSupply(getCoin, amount)
error = error || isLessReserve(spendCoin, needDel)
}
// error = error || isInfluentFunds(amount, spendCoin);
if (error) {
return {
success: false,
...error
}
}
return {
success: true,
value: estimated
}
}
```