symbol search in tv
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
"color": "^4.2.3",
|
||||
"core-js": "^3.29.0",
|
||||
"ethers": "^6.7.1",
|
||||
"flexsearch": "^0.7.43",
|
||||
"pinia": "2.1.6",
|
||||
"roboto-fontface": "*",
|
||||
"socket.io-client": "^4.7.2",
|
||||
|
||||
5042
public/metadata.json
Normal file
5042
public/metadata.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,6 @@
|
||||
import {useChartOrderStore} from "@/orderbuild.js";
|
||||
import {invokeCallbacks, prototype} from "@/common.js";
|
||||
import datafeed from "@/charts/datafeed.js";
|
||||
|
||||
export let widget = null
|
||||
export let chart = null
|
||||
@@ -21,12 +22,12 @@ export function initWidget(el) {
|
||||
library_path: "/charting_library/",
|
||||
// debug: true,
|
||||
autosize: true,
|
||||
symbol: 'AAPL',
|
||||
// symbol: 'Uniswap:WETH/USD', // use this for ohlc
|
||||
// symbol: 'AAPL',
|
||||
symbol: 'UNIv3:WETH/USDC', // use this for ohlc
|
||||
interval: '1D',
|
||||
container: el,
|
||||
datafeed: new Datafeeds.UDFCompatibleDatafeed("https://demo-feed-data.tradingview.com"),
|
||||
// datafeed: datafeed, // use this for ohlc
|
||||
// datafeed: new Datafeeds.UDFCompatibleDatafeed("https://demo-feed-data.tradingview.com"),
|
||||
datafeed: datafeed, // use this for ohlc
|
||||
locale: "en",
|
||||
disabled_features: [],
|
||||
enabled_features: ['saveload_separate_drawings_storage'],
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import {jBars} from './jBars.js';
|
||||
import {metadata} from "@/version.js";
|
||||
import FlexSearch from "flexsearch";
|
||||
|
||||
const lastBarsCache = new Map();
|
||||
|
||||
@@ -9,29 +11,81 @@ const configurationData = {
|
||||
['1', '3', '5', '10', '15', '30', '60', '120', '240', '480', '720', '1D', '2D', '3D', '1W'],
|
||||
|
||||
// The `exchanges` arguments are used for the `searchSymbols` method if a user selects the exchange
|
||||
exchanges: [{
|
||||
value: 'Uniswap',
|
||||
name: 'Uniswap',
|
||||
desc: 'Uniswap',
|
||||
exchanges: [
|
||||
// {
|
||||
// value: 'UNIv2',
|
||||
// name: 'Uniswap v2',
|
||||
// desc: 'Uniswap v2',
|
||||
// },
|
||||
{
|
||||
value: 'UNIv3',
|
||||
name: 'Uniswap v3',
|
||||
desc: 'Uniswap v3',
|
||||
logo: 'https://upload.wikimedia.org/wikipedia/commons/e/e7/Uniswap_Logo.svg',
|
||||
},
|
||||
],
|
||||
// The `symbols_types` arguments are used for the `searchSymbols` method if a user selects this symbol type
|
||||
symbols_types: [{
|
||||
name: 'crypto',
|
||||
value: 'crypto',
|
||||
},
|
||||
symbols_types: [
|
||||
{name: 'swap', value: 'swap',},
|
||||
],
|
||||
};
|
||||
|
||||
// Obtains all symbols for all exchanges supported by CryptoCompare API
|
||||
|
||||
const tokenMap = {}
|
||||
const poolMap = {}
|
||||
let symbols = null
|
||||
const indexer = new FlexSearch.Document({
|
||||
document: {id: 'id', index: ['id', 'a', 'b', 'q', 'bs', 'qs', 'e', 'd']},
|
||||
charset: {split: /\W+/},
|
||||
tokenize: 'forward',
|
||||
})
|
||||
|
||||
|
||||
async function getAllSymbols() {
|
||||
return [{
|
||||
symbol: 'WETH/USD',
|
||||
full_name: 'Uniswap:WETH/USD',
|
||||
description: 'WETH/USD 42161/0xC31E54c7a869B9Fc',
|
||||
exchange: 'Uniswap',
|
||||
type: 'crypto'}
|
||||
];
|
||||
const built = {} // keyed by (base,quote) so we only list one pool per pair even if there are many fee tiers
|
||||
if (symbols===null) {
|
||||
symbols = {}
|
||||
for (const t of metadata['t'])
|
||||
tokenMap[t['a']] = t
|
||||
metadata['p'].forEach((p)=>{
|
||||
poolMap[p['a']] = p
|
||||
// todo inversion
|
||||
const base = tokenMap[p['b']];
|
||||
const quote = tokenMap[p['q']];
|
||||
if (!base) {
|
||||
console.log(`No token ${p['b']} found`)
|
||||
return
|
||||
}
|
||||
if (!quote) {
|
||||
console.log(`No token ${p['q']} found`)
|
||||
return
|
||||
}
|
||||
const symbol = base['s'] + '/' + quote['s']
|
||||
const exchange = ['UNIv2','UNIv3'][p['e']]
|
||||
const full_name = exchange+':'+symbol
|
||||
if (full_name in built)
|
||||
return
|
||||
built[full_name] = true
|
||||
const longExchange = ['Uniswap v2', 'Uniswap v3',][p['e']]
|
||||
const description = `${base['n']} / ${quote['n']}`
|
||||
const type = 'swap'
|
||||
symbols[full_name] = {symbol, full_name, description, exchange, type,}
|
||||
indexer.add({
|
||||
// key
|
||||
id: full_name,
|
||||
// addresses
|
||||
a: p['a'],
|
||||
b: p['b'],
|
||||
q: p['q'],
|
||||
// symbols
|
||||
bs: base['s'],
|
||||
qs: quote['s'],
|
||||
e: exchange,
|
||||
d: description,
|
||||
})
|
||||
})
|
||||
}
|
||||
return Object.values(symbols)
|
||||
}
|
||||
|
||||
export default {
|
||||
@@ -40,6 +94,24 @@ export default {
|
||||
setTimeout(() => callback(configurationData));
|
||||
},
|
||||
|
||||
// searchSymbols: async (
|
||||
// userInput,
|
||||
// exchange,
|
||||
// symbolType,
|
||||
// onResultReadyCallback,
|
||||
// ) => {
|
||||
// console.log('[searchSymbols]: Method call');
|
||||
// const symbols = await getAllSymbols();
|
||||
// const newSymbols = symbols.filter(symbol => {
|
||||
// const isExchangeValid = exchange === '' || symbol.exchange === exchange;
|
||||
// const isFullSymbolContainsInput = symbol.full_name
|
||||
// .toLowerCase()
|
||||
// .indexOf(userInput.toLowerCase()) !== -1;
|
||||
// return isExchangeValid && isFullSymbolContainsInput;
|
||||
// });
|
||||
// onResultReadyCallback(newSymbols);
|
||||
// },
|
||||
|
||||
searchSymbols: async (
|
||||
userInput,
|
||||
exchange,
|
||||
@@ -47,15 +119,14 @@ export default {
|
||||
onResultReadyCallback,
|
||||
) => {
|
||||
console.log('[searchSymbols]: Method call');
|
||||
const symbols = await getAllSymbols();
|
||||
const newSymbols = symbols.filter(symbol => {
|
||||
const isExchangeValid = exchange === '' || symbol.exchange === exchange;
|
||||
const isFullSymbolContainsInput = symbol.full_name
|
||||
.toLowerCase()
|
||||
.indexOf(userInput.toLowerCase()) !== -1;
|
||||
return isExchangeValid && isFullSymbolContainsInput;
|
||||
});
|
||||
onResultReadyCallback(newSymbols);
|
||||
// todo limit results by exchange. use a separate indexer per exchange?
|
||||
const found = indexer.search(userInput, 10)
|
||||
console.log('found', found)
|
||||
const result = []
|
||||
for (const f of found)
|
||||
for (const key of f.result)
|
||||
result.push(symbols[key])
|
||||
onResultReadyCallback(result);
|
||||
},
|
||||
|
||||
resolveSymbol: async (
|
||||
@@ -66,9 +137,7 @@ export default {
|
||||
) => {
|
||||
console.log('[resolveSymbol]: Method call', symbolName);
|
||||
const symbols = await getAllSymbols();
|
||||
const symbolItem = symbols.find(({
|
||||
full_name,
|
||||
}) => full_name === symbolName);
|
||||
const symbolItem = symbols[symbolName]
|
||||
if (!symbolItem) {
|
||||
console.log('[resolveSymbol]: Cannot resolve symbol', symbolName);
|
||||
onResolveErrorCallback('cannot resolve symbol');
|
||||
|
||||
@@ -15,6 +15,7 @@ import { registerPlugins } from '@/plugins'
|
||||
import '@/styles/style.scss'
|
||||
import {detectChain} from "@/blockchain/wallet.js";
|
||||
import "./socket.js"
|
||||
import "./version.js"
|
||||
|
||||
BigInt.prototype.toJSON = function() { return this.toString() }
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import {defineStore} from 'pinia'
|
||||
import {knownTokens} from "@/knownTokens.js";
|
||||
import {computed, ref} from "vue";
|
||||
import {version} from "@/version.js";
|
||||
|
||||
// USING THE STORE:
|
||||
//
|
||||
@@ -30,10 +31,6 @@ function timestamp() {
|
||||
return Math.round(new Date().getTime() / 1000)
|
||||
}
|
||||
|
||||
const response = await fetch('/version.json')
|
||||
const version = await response.json()
|
||||
console.log('version', version)
|
||||
|
||||
export const useStore = defineStore('app', ()=> {
|
||||
const clock = ref(timestamp())
|
||||
const nav = ref(false) // controls opening navigation drawer
|
||||
|
||||
6
src/version.js
Normal file
6
src/version.js
Normal file
@@ -0,0 +1,6 @@
|
||||
const versionPromise = fetch('/version.json').then(async (response)=>await response.json())
|
||||
const metadataPromise = fetch('/metadata.json').then(async (response)=>await response.json())
|
||||
|
||||
export const version = await versionPromise
|
||||
export const metadata = await metadataPromise
|
||||
console.log('version', version)
|
||||
@@ -772,6 +772,11 @@ flatted@^3.2.9:
|
||||
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.9.tgz#7eb4c67ca1ba34232ca9d2d93e9886e611ad7daf"
|
||||
integrity sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==
|
||||
|
||||
flexsearch@^0.7.43:
|
||||
version "0.7.43"
|
||||
resolved "https://registry.yarnpkg.com/flexsearch/-/flexsearch-0.7.43.tgz#34f89b36278a466ce379c5bf6fb341965ed3f16c"
|
||||
integrity sha512-c5o/+Um8aqCSOXGcZoqZOm+NqtVwNsvVpWv6lfmSclU954O3wvQKxxK8zj74fPaSJbXpSLTs4PRhh+wnoCXnKg==
|
||||
|
||||
fs.realpath@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||
|
||||
Reference in New Issue
Block a user