new pool selection dialog and liquidity
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import {useChartOrderStore} from "@/orderbuild.js";
|
||||
import {invokeCallbacks, prototype} from "@/common.js";
|
||||
import {DataFeed, defaultSymbol, feelessTickerKey, getAllSymbols, lookupSymbol} from "@/charts/datafeed.js";
|
||||
import {intervalToSeconds, SingletonCoroutine} from "@/misc.js";
|
||||
import {intervalToSeconds, SingletonCoroutine, toHuman, toPrecision} from "@/misc.js";
|
||||
import {usePrefStore, useStore} from "@/store/store.js";
|
||||
import {tvCustomThemes} from "../../theme.js";
|
||||
|
||||
@@ -83,51 +83,49 @@ const subscribeEvents = [
|
||||
*/
|
||||
|
||||
|
||||
let feeDropdown = null
|
||||
let poolButtonTextElement = null
|
||||
|
||||
export function initFeeDropdown(w) {
|
||||
widget = w
|
||||
widget.createDropdown(
|
||||
{
|
||||
title: 'Fees',
|
||||
tooltip: 'Choose Fee Tier',
|
||||
items: [/*{title: 'Automatic Fee Selection', onSelect: () => {log('autofees')}}*/],
|
||||
icon: `<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28"><g fill="none" stroke="currentColor"><circle cx="10" cy="10" r="2.5"/><circle cx="18" cy="18" r="2.5"/><path stroke-linecap="square" d="M17.5 7.5l-7 13"/></g></svg>`,
|
||||
}
|
||||
).then(dropdown => {
|
||||
feeDropdown = dropdown;
|
||||
updateFeeDropdown()
|
||||
})
|
||||
export function initFeeDropdown() {
|
||||
const button = widget.createButton()
|
||||
button.setAttribute('title', 'See Pool Info and Choose Fee');
|
||||
button.addEventListener('click', function() { co.showPoolSelection = true });
|
||||
button.style.height = '34px';
|
||||
button.style.display = 'flex';
|
||||
button.style.alignItems = 'center';
|
||||
button.addEventListener('mouseover', () => {
|
||||
button.style.backgroundColor = 'rgb(60,60,60)';
|
||||
});
|
||||
button.addEventListener('mouseout', () => {
|
||||
button.style.backgroundColor = '';
|
||||
});
|
||||
button.id = 'pool-button'
|
||||
button.style.margin = '2px 0';
|
||||
button.style.borderRadius = '4px';
|
||||
button.classList.add('pool-button')
|
||||
|
||||
const span = document.createElement('span');
|
||||
span.textContent = 'Pool';
|
||||
span.style.marginY = 'auto';
|
||||
button.appendChild(span);
|
||||
poolButtonTextElement = span
|
||||
|
||||
updateFeeDropdown()
|
||||
}
|
||||
|
||||
export function updateFeeDropdown() {
|
||||
if (feeDropdown === null) return
|
||||
if (poolButtonTextElement===null) return
|
||||
const symbolItem = useChartOrderStore().selectedSymbol
|
||||
let items
|
||||
if (symbolItem === null)
|
||||
items = [{title: '0.00%'}]
|
||||
else {
|
||||
const feeGroup = symbolItem.feeGroup
|
||||
items = feeGroup.map((p) => {
|
||||
const [_addr, fee] = p
|
||||
return {
|
||||
title: (fee / 10000).toFixed(2) + '%',
|
||||
onSelect: ()=>{
|
||||
if (fee !== symbolItem.fee)
|
||||
selectPool(fee)
|
||||
},
|
||||
}
|
||||
})
|
||||
let text = 'Pool '
|
||||
text += (symbolItem.fee / 10000).toFixed(2) + '%'
|
||||
const index = symbolItem.feeGroup.findIndex((p) => p[1] === symbolItem.fee)
|
||||
if (symbolItem.liquiditySymbol) {
|
||||
const liq = symbolItem.liquidities[index]
|
||||
if (symbolItem.liquiditySymbol === 'USD')
|
||||
text += ` $${toHuman(liq)}`
|
||||
else
|
||||
text = ` ${toHuman(liq)} ${symbolItem.liquiditySymbol}`
|
||||
}
|
||||
feeDropdown.applyOptions({items})
|
||||
}
|
||||
|
||||
function selectPool(fee) {
|
||||
const co = useChartOrderStore();
|
||||
const s = co.selectedSymbol;
|
||||
const ticker = feelessTickerKey(s.ticker) + '|' + fee
|
||||
if (ticker !== s.ticker)
|
||||
setSymbolTicker(ticker).catch((e)=>console.error('Could not change TV symbol to', ticker))
|
||||
poolButtonTextElement.textContent = text
|
||||
}
|
||||
|
||||
export function initWidget(el) {
|
||||
@@ -145,9 +143,9 @@ export function initWidget(el) {
|
||||
container: el,
|
||||
datafeed: DataFeed, // use this for ohlc
|
||||
locale: "en",
|
||||
disabled_features: [],
|
||||
enabled_features: ['saveload_separate_drawings_storage'],
|
||||
drawings_access: {type: 'white', tools: [],}, // show no tools
|
||||
disabled_features: ['main_series_scale_menu',],
|
||||
enabled_features: ['saveload_separate_drawings_storage',],
|
||||
// drawings_access: {type: 'white', tools: [],}, // show no tools
|
||||
custom_themes: tvCustomThemes,
|
||||
theme: useStore().theme,
|
||||
timezone: prefs.timezone,
|
||||
@@ -155,7 +153,7 @@ export function initWidget(el) {
|
||||
// Chart Overrides
|
||||
// https://www.tradingview.com/charting-library-docs/latest/customization/overrides/chart-overrides
|
||||
overrides: {
|
||||
// "mainSeriesProperties.priceAxisProperties.log": false,
|
||||
"mainSeriesProperties.priceAxisProperties.log": false,
|
||||
}
|
||||
|
||||
});
|
||||
@@ -168,7 +166,7 @@ export function initWidget(el) {
|
||||
widget.subscribe('onSelectedLineToolChanged', onSelectedLineToolChanged)
|
||||
widget.subscribe('mouse_down', mouseDown)
|
||||
widget.subscribe('mouse_up', mouseUp)
|
||||
widget.headerReady().then(()=>initFeeDropdown(widget))
|
||||
widget.headerReady().then(()=>initFeeDropdown())
|
||||
widget.onChartReady(initChart)
|
||||
console.log('tv widget initialized')
|
||||
}
|
||||
|
||||
@@ -6,7 +6,9 @@ import {useStore} from "@/store/store.js";
|
||||
import {subOHLC, unsubOHLC} from "@/blockchain/ohlcs.js";
|
||||
import {ohlcStart} from "@/charts/chart-misc.js";
|
||||
|
||||
import {timestamp} from "@/common.js";
|
||||
import {timestamp, USD_FIAT} from "@/common.js";
|
||||
import {erc20Contract} from "@/blockchain/contract.js";
|
||||
import {provider} from "@/blockchain/wallet.js";
|
||||
|
||||
const DEBUG_LOGGING = false
|
||||
const log = DEBUG_LOGGING ? console.log : ()=>{}
|
||||
@@ -131,9 +133,9 @@ function addSymbol(chainId, p, base, quote, inverted) {
|
||||
else
|
||||
feeGroups[feelessKey] = [[symbolInfo.address, symbolInfo.fee]]
|
||||
symbolInfo.feeGroup = feeGroups[feelessKey]
|
||||
if (defaultSymbol===null) {
|
||||
console.log(`invertedDefault(${symbolInfo.base.s}, ${symbolInfo.quote.s})`,invertedDefault(symbolInfo.base.a, symbolInfo.quote.a))
|
||||
}
|
||||
// if (defaultSymbol===null) {
|
||||
// console.log(`invertedDefault(${symbolInfo.base.s}, ${symbolInfo.quote.s})`,invertedDefault(symbolInfo.base.a, symbolInfo.quote.a))
|
||||
// }
|
||||
if (defaultSymbol===null && !invertedDefault(symbolInfo.base.a, symbolInfo.quote.a)) {
|
||||
console.log('setting default symbol', symbolInfo.base.s, symbolInfo.quote.s, symbolInfo.base.a, symbolInfo.quote.a)
|
||||
defaultSymbol = _symbols[ticker]
|
||||
@@ -384,12 +386,45 @@ export const DataFeed = {
|
||||
}
|
||||
const co = useChartOrderStore();
|
||||
co.selectedSymbol = symbolItem
|
||||
const feelessKey = feelessTickerKey(symbolItem.ticker)
|
||||
const symbolsByFee = feeGroups[feelessKey]
|
||||
symbolsByFee.sort((a,b)=>a.fee-b.fee)
|
||||
const pool = symbolsByFee[Math.floor((symbolsByFee.length - 1)/2)] // median rounded down
|
||||
// noinspection JSValidateTypes
|
||||
co.selectedPool = pool // todo remove
|
||||
|
||||
let ticker = symbolItem.ticker
|
||||
try {
|
||||
if (!symbolItem.liquiditySymbol) {
|
||||
// fetch liquidities and cache on the symbolItem
|
||||
const inv = invertedDefault(symbolItem.base.a, symbolItem.quote.a)
|
||||
const markToken = inv ? symbolItem.base : symbolItem.quote
|
||||
const mark = useStore().markPrice(markToken.a)
|
||||
const token = await erc20Contract(markToken.a, provider)
|
||||
const liquidities = await Promise.all(symbolItem.feeGroup.map(
|
||||
async ([addr, fee]) => await token.balanceOf(addr)
|
||||
))
|
||||
symbolItem.liquidities = liquidities.map(l => Number(l / 10n ** BigInt(markToken.d)))
|
||||
if (mark) {
|
||||
symbolItem.liquidities = symbolItem.liquidities.map(l => l * mark)
|
||||
symbolItem.liquiditySymbol = 'USD'
|
||||
} else {
|
||||
symbolItem.liquiditySymbol = symbolItem.quote.s
|
||||
}
|
||||
}
|
||||
const liqsAndFees = []
|
||||
for (let i=0; i<symbolItem.feeGroup.length; i++) {
|
||||
const [addr, fee] = symbolItem.feeGroup[i]
|
||||
const liq = symbolItem.liquidities[i]
|
||||
liqsAndFees.push([liq, fee])
|
||||
if (fee === symbolItem.fee)
|
||||
symbolItem.liquidity = liq
|
||||
}
|
||||
liqsAndFees.sort((a,b) => b[0] - a[0])
|
||||
const highestLiquidityFee = liqsAndFees[0][1]
|
||||
// console.log('liquidities', liqsAndFees)
|
||||
// console.log('best liquidity', highestLiquidityFee, liqsAndFees[0][0], symbolItem.liquiditySymbol)
|
||||
ticker = feelessTickerKey(ticker) + '|' + highestLiquidityFee
|
||||
}
|
||||
catch (error) {
|
||||
// use the median fee group instead
|
||||
console.log('liquidity fetch error', error)
|
||||
}
|
||||
|
||||
// LibrarySymbolInfo
|
||||
// https://www.tradingview.com/charting-library-docs/latest/api/interfaces/Charting_Library.LibrarySymbolInfo
|
||||
const symbolInfo = {
|
||||
|
||||
@@ -339,7 +339,7 @@ export class Shape {
|
||||
|
||||
onPoints(points) {} // the control points of an existing shape were changed
|
||||
|
||||
onDrag(points) { console.log('shape ondrag'); this.onPoints(points) }
|
||||
onDrag(points) { this.onPoints(points) }
|
||||
|
||||
setProps(props) {
|
||||
if (!props || Object.keys(props).length===0) return
|
||||
|
||||
Reference in New Issue
Block a user