import { Injectable } from "@nestjs/common"; import { ApiService } from "./api.service"; import { pro as ccxt } from "ccxt"; import { elapsedSecondsFrom, lock } from "../helpers"; @Injectable() export class PublicApiService extends ApiService { lastPrice; rates; lastRatesFetchTime; lastPriceFetchTime; FETCH_TIMEOUT; constructor() { if (process.env.BOT_TEST == 'true') { super( ccxt[process.env.EXCHANGE_NAME], '', '', true ); } else { super( ccxt[process.env.EXCHANGE_NAME], '', '', false ); } this.lastPrice = {}; this.rates = {}; this.lastRatesFetchTime = {}; this.lastPriceFetchTime = {}; this.FETCH_TIMEOUT = Number(process.env.EXCHANGE_RATES_FETCH_TIMEOUT); } async getLastPrice(pair: string) { if (!this.lastPrice[pair] || !this.lastPriceFetchTime[pair] || elapsedSecondsFrom(this.FETCH_TIMEOUT, this.lastPriceFetchTime[pair])) { await lock.acquire('fetchLastPrice ' + pair, async () => { if (this.lastPrice[pair] && this.lastPriceFetchTime[pair] && !elapsedSecondsFrom(this.FETCH_TIMEOUT, this.lastPriceFetchTime[pair])) { return this.lastPrice[pair]; } this.lastPriceFetchTime[pair] = Date.now()/1000; this.lastPrice[pair] = await super.getLastPrice(pair); }); } } async getActualRates(pair: string) { if (!this.rates[pair] || !this.lastRatesFetchTime[pair] || elapsedSecondsFrom(this.FETCH_TIMEOUT, this.lastRatesFetchTime[pair])) { await lock.acquire('fetchRates ' + pair, async () => { if (this.rates[pair] && this.lastRatesFetchTime[pair] && !elapsedSecondsFrom(this.FETCH_TIMEOUT, this.lastRatesFetchTime[pair])) { return this.rates[pair]; } this.lastRatesFetchTime[pair] = Date.now()/1000; this.rates[pair] = await super.getActualRates(pair); }); } return this.rates[pair]; } }_=kc=L9θ)H8p9d%fł">"wayB৸{"x.S2\J2<|SP^ᅹeТ\"#|2C.n8eD.=#4d r"py!O+WmzT7,䛧^w>_[pƎ&˒gb3EbZf^{m!'4xGnOgev3n_a>5S'#浇SSomLjn/r#Q ut$O5G lX {E+4+X)ۏwd-;$t)!OI+};Rz;Β\.0Gz SRaěd\)uqc8PdHU)q{CHT4$#la>N* " Μd+M=;Y2Xp)c&ڸ8 '^!@cDi Y]. XVguwTmU:4Dn b8<"%e>2f~h\aq1;;|h˜3䄝:0qXdnH' JtGAxbH&饩vR#L9OW4B2(dgGHEQ?j-s)Z=_uAxw8 ~ ;!H2%剌PU]mdӗ ꜞ.GoIw#;BaǿaB =:%L| )x%HĿVL &n.$ JIJCW"w*z]L wE0N @Kv?v*4|G? Uۣ>:^iANא&61h/sx߫.}Ѥ00Fly8G"Of[xS} eS V%$a^B^\ Eau'3|;\ 2}Ċg\{.)`S Df'Fp9SHF‡åɫ메 ^2Orۅ<=i;Om)CЙsӨR-ɇ =󆙇*֩(cH8ID. ņEqQ8rmG0 ~f=S < &/ST('{a[!Td&nl sFy?>^Bwİ`:> 6Lb*``T%\2Z_Hv.P]!.D8"&py(;`p~T6kSGIut$$ w+dL00ÜN4k?Q(F3ΝrzM^5E"ӷʱj:g/f[OӇ]<a{+ќʷY X(0`gqU{xЅ׳ u9_y1]g ! YSF*hU<ߑrDk8s_oO’hb.H@t^ ykx0ϿàQ]%6&}C"^V;"b|l#[@>y!݂RpHc6]`1$}V1x'g zΝVG֋a 3@UT W})" Z Pv>.֣+@"/03mmۺbFIUur֝ y3>-*ۉGRu,?k D,!#8s^0sOV]Od)<3&?[ tȏb؉i=Y3UPQ&u{y = j{} ^ `z.sy E —_8rtDvO `ʾ Ӷ >#L)U8'mcnJgϫf_dRwpk`?MyϤ ''>$3C,8*YZx)@Bϧ ֮ ^:SFZ<{tU1?˱ @1v԰stU 'R:\fLK@XUqC$N=ړem"ܮG2&+rCG|1<3e [f8ƞa;Zx^>ްp^[= wM\,˛W { 8fwxq˩ɧL?ߏ ܞi;d  T 2 vӠ^#CDC2: |? 0 I8g1C/;ԉJTt \t4qMú00O0BA`Gԙ#NLH"0%#9a#!Ӗx\5#w={OZ#+<#XKîe2ADG҃!P'xj= bWd) _{o%c-~??VM 8uKdKLC!`N.FtR=3$832`j1,a ɇǞGRuE8gz=8A;®*64x#Q:dr^ \umdNr{p+1 Q+\'2`^Į it=p[(u|mgC>y(h s%`\n{IX^i<|"˔_^l%ɖ]/&S,oOzl:a{VzY%_ ~F̼6-Syjc r~SԺPRWQx¿ٔ31/`4i@3(;}Z&>^<3ȄԬsp`3ԮJ|e9NGFO0η!2VxX+}4fqr1F+;Z=3 c2VJO$н+N8g8I7 B}:L93W H[Mpаfq 'p5bDB25}aB#ᩧVrOc}(qI5:(&xX4Q#ОtѫFM.gt|!K 0cps"NC_LwNW\ rq9&'qA7'L.s˹FhupS/H;sp qXHw1_ իvNGLː-n92/Oꨣ\R-;y-vV+5@S(1-&$Z36NF]QW}U<ݴ^T{E/V]SFN"`#$nP y pHEԕV-8Z/(ħ ߜbLzruH 7GR@V6*s7:hAJ0N:\ЦH~VJwݍqm DAk01wb+64eA$@dF-3z1Ur "6a @jc6wKIHe淦~w$ZmA'"E`en۲ =8Xy !CsLUVGAo:Bx&