price subscriptions
This commit is contained in:
84
src/blockchain/prices.js
Normal file
84
src/blockchain/prices.js
Normal file
@@ -0,0 +1,84 @@
|
||||
import {socket} from "@/socket.js";
|
||||
import {useStore} from "@/store/store.js";
|
||||
import {Exchange} from "@/blockchain/orderlib.js";
|
||||
import {uniswapV3PoolAddress} from "@/blockchain/uniswap.js";
|
||||
import {ethers, FixedNumber} from "ethers";
|
||||
import {erc20Abi, uniswapV3PoolAbi} from "@/blockchain/abi.js";
|
||||
|
||||
const subs = {} // key is route and value is a subscription counter
|
||||
|
||||
|
||||
export function subPrices( routes ) {
|
||||
const subRoutes = []
|
||||
let chainId = null
|
||||
for( const route of routes ) {
|
||||
if( !(route in subRoutes) || subRoutes[route] === 0 ) {
|
||||
subRoutes[route] = 1
|
||||
console.log('subscribing to pool', route.pool)
|
||||
subRoutes.push(route)
|
||||
}
|
||||
else {
|
||||
subRoutes[route]++
|
||||
if( chainId !== null && route.chainId !== chainId )
|
||||
throw Error('cannot mix chainIds in a subscription list')
|
||||
chainId = route.chainId
|
||||
}
|
||||
}
|
||||
if( subRoutes.length ) {
|
||||
socket.emit('subPools', chainId, routes.map((r)=>r.address) )
|
||||
// perform a local query if necessary
|
||||
for( const route of subRoutes ) {
|
||||
const s = useStore()
|
||||
if( !(route.address in s.poolPrices) ) {
|
||||
getPriceForRoute(route).then((price)=>s.poolPrices[route.address]=price)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function unsubPrices( routes ) {
|
||||
let chainId = null
|
||||
const unsubAddrs = []
|
||||
for( const route of routes ) {
|
||||
if( !(route in subs) ) {
|
||||
console.error('unsubscribed to a nonexistent route', route)
|
||||
}
|
||||
else {
|
||||
subs[route]--
|
||||
if( subs[route] === 0 ) {
|
||||
unsubAddrs.push(route.pool)
|
||||
if( chainId !== null && route.chainId !== chainId )
|
||||
throw Error('cannot mix chainIds in a subscription list')
|
||||
console.log('unsubscribing from pool', route.pool)
|
||||
chainId = route.chainId
|
||||
}
|
||||
else if( subs[route] < 0 ) {
|
||||
console.error('unsubscribed to an already unsubbed route', route)
|
||||
subs[route] = 0 // fix
|
||||
}
|
||||
}
|
||||
}
|
||||
if( unsubAddrs.length )
|
||||
socket.emit('unsubPool', chainId, unsubAddrs )
|
||||
}
|
||||
|
||||
|
||||
async function getPriceForRoute(route) {
|
||||
console.log('route is',route)
|
||||
if( route.exchange === Exchange.UniswapV3 ) {
|
||||
const addr = uniswapV3PoolAddress(route.chainId, route.token0.address, route.token1.address, route.fee)
|
||||
const provider = useStore().provider;
|
||||
if( provider === null ) {
|
||||
console.error('provider was null during getPriceForRoute')
|
||||
return null
|
||||
}
|
||||
const pool = new ethers.Contract(addr, uniswapV3PoolAbi, provider)
|
||||
const got = await pool.slot0()
|
||||
const [sqrtPrice,,,,,,] = got
|
||||
const spn = Number(sqrtPrice)
|
||||
const price = spn*spn/2**(96*2) * 10**(route.token0.decimals-route.token1.decimals)
|
||||
console.log(`price for ${route.token0.symbol}/${route.token1.symbol}`,price)
|
||||
}
|
||||
else
|
||||
throw Error(`Unsupported exchange ${route.exchange}`)
|
||||
}
|
||||
Reference in New Issue
Block a user