import {FixedNumber} from "ethers"; import {usePrefStore, useStore} from "@/store/store.js"; import {token} from "@/blockchain/token.js"; export class SingletonCoroutine { constructor(f, delay=10, retry=true) { this.f = f this.delay = delay this.timeout = null this.args = null } pending() { return this.timeout !== null } invoke(/*arguments*/) { this.args = arguments // console.log('invoke', arguments) if( this.timeout === null ) this.timeout = setTimeout(this.onTimeout, this.delay, this) } async onTimeout(self) { try { await self.f(...self.args) } catch (e) { if( self.retry ) { console.log('retrying', this.f, 'due to error', e) self.timeout = null self.invoke(self.args) } else console.error(e) } finally { self.timeout = null } } } export const vAutoSelect = { beforeMount: (el) => { const input = el.querySelector('input') input.onfocus = () => setTimeout(() => input.select(), 0) } } export const uint32max = 4294967295n export const uint64max = 18446744073709551615n export function tokenNumber(token, balance) { return FixedNumber.fromValue(balance, token.decimals, {decimals:token.decimals, width: 256}) } export function tokenFloat(token, balance) { return tokenNumber(token,balance).toUnsafeFloat() } export function routeInverted(route) { const s = useStore() return route && (route.token0 === s.tokenA) === s.inverted } export function intervalString(seconds) { if( seconds < 1 ) return 'now' else if( seconds < 60 ) return `${seconds} seconds` else if( seconds < 3600 ) return `${(seconds/60).toFixed(1)} minutes` else if( seconds < 86400 ) return `${(seconds/3600).toFixed(1)} hours` else return `${(seconds/86400).toFixed(1)} days` } const _dateFormat = new Intl.DateTimeFormat( undefined, {dateStyle: 'medium', timeStyle: 'short'}) export function dateString(seconds) { const date = new Date(seconds*1000) return _dateFormat.format(date) } export function timestamp(date=null) { if(date===null) date = new Date() return Math.round(date.getTime() / 1000) } export function pairKey(tokenA, tokenB) { const token0 = tokenA.a < tokenB.a ? tokenA.a : tokenB.a const token1 = tokenA.a > tokenB.a ? tokenA.a : tokenB.a return [token0, token1]; } export function pairPriceAddr(baseTokenAddr, quoteTokenAddr, price) { const baseToken = token(baseTokenAddr) const quoteToken = token(quoteTokenAddr) if( !baseToken || !quoteToken ) return null return pairPrice(baseToken, quoteToken, price) } export function pairPrice(baseToken, quoteToken, price, decimals=null) { if( price === null || price === undefined ) return price if( decimals === null ) decimals = baseToken.decimals-quoteToken.decimals console.log('pairPrice', baseToken, quoteToken, price, decimals) if( decimals >= 0 ) price /= 10 ** decimals else price *= 10 ** -decimals const invertedKey = pairKey(baseToken, quoteToken); const prefs = usePrefStore() if( !(invertedKey in prefs.inverted) ) { // todo prefer stablecoins as the quote asset prefs.inverted[invertedKey] = false } if( prefs.inverted[invertedKey] ) price = 1/price return price } export const sleep = ms => new Promise(r => setTimeout(r, ms)) export function builderDefaults(builder, defaults) { for (const k in defaults) if (builder[k] === undefined) builder[k] = defaults[k] instanceof Function ? defaults[k]() : defaults[k] }