diff --git a/src/blockchain/route.js b/src/blockchain/route.js
index a42a175..06e612d 100644
--- a/src/blockchain/route.js
+++ b/src/blockchain/route.js
@@ -1,9 +1,12 @@
import {Exchange} from "@/blockchain/orderlib.js";
+import {useOrderStore, useStore} from "@/store/store.js";
+import {queryHelperContract} from "@/blockchain/contract.js";
+import {SingletonCoroutine} from "@/misc.js";
export async function findRoute(helper, chainId, tokenA, tokenB) {
- console.log('getting raw routes', helper, tokenA.address, tokenB.address)
- const rawRoutes = await helper.getRoutes(tokenA.address, tokenB.address)
+ console.log('getting raw routes', helper, tokenA.a, tokenB.a)
+ const rawRoutes = await helper.getRoutes(tokenA.a, tokenB.a)
// todo expose all available pools
console.log('raw routes', rawRoutes)
let result = null // we actually only find a single pool for now
@@ -15,11 +18,41 @@ export async function findRoute(helper, chainId, tokenA, tokenB) {
case 0: // UniswapV2
throw Error('Uniswap V2 not yet supported')
case 1: // UniswapV3
- const [token0, token1] = tokenA.address < tokenB.address ? [tokenA, tokenB] : [tokenB, tokenA]
- result = {chainId, exchange: Exchange.UniswapV3, pool, fee, token0, token1}
+ const inverted = tokenA.a < tokenB.a;
+ const [token0, token1] = inverted ? [tokenA, tokenB] : [tokenB, tokenA]
+ result = {chainId, exchange: Exchange.UniswapV3, pool, fee, token0, token1, inverted}
break
}
}
}
return result ? [result] : []
}
+
+async function componentFindRoute() {
+ const s = useStore()
+ const os = useOrderStore()
+ const tokenA = os.tokenA
+ const tokenB = os.tokenB
+ os.routes = []
+ if (!tokenA || !tokenB)
+ return
+ console.log('finding route', s.chainId.value, tokenA, tokenB)
+ os.routesPending = true
+ try {
+ console.log('getting query helper')
+ const helper = await queryHelperContract(s.helper, s.provider)
+ if (!helper) {
+ console.log('no helper')
+ } else {
+ const result = await findRoute(helper, s.chainId.value, tokenA, tokenB)
+ console.log('found route', result)
+ os.routes = result
+ }
+ } catch (e) {
+ console.log('ignoring routes exception', e)
+ } finally {
+ os.routesPending = false
+ }
+}
+
+export const routeFinder = new SingletonCoroutine(componentFindRoute, 10)
diff --git a/src/blockchain/wallet.js b/src/blockchain/wallet.js
index 8f4672d..c4812d4 100644
--- a/src/blockchain/wallet.js
+++ b/src/blockchain/wallet.js
@@ -131,7 +131,10 @@ async function _discoverVaults(owner) {
console.error(`bad vault version ${version}`)
}
catch (e) {
- console.log(`no vault ${num} at ${addr}`, e)
+ if( e.value==='0x' && e.code==='BAD_DATA' )
+ console.log(`no vault ${num} at ${addr}`)
+ else
+ console.error(`routeFinder failed`, e)
}
if( s.account == owner ) { // double-check the account since it could have changed during our await
s.vaults = result
diff --git a/src/charts/chart.js b/src/charts/chart.js
index f09c128..6dd724b 100644
--- a/src/charts/chart.js
+++ b/src/charts/chart.js
@@ -1,10 +1,28 @@
import {useChartOrderStore} from "@/orderbuild.js";
import {invokeCallbacks, prototype} from "@/common.js";
-import datafeed from "@/charts/datafeed.js";
+import datafeed, {lookupSymbol} from "@/charts/datafeed.js";
export let widget = null
export let chart = null
export let crosshairPoint = null
+let symbolChangedCbs = [] // callbacks for TV's chart.onSymbolChanged()
+let lastSymbolChangedArgs = null
+
+export function addSymbolChangedCallback(cb) {
+ symbolChangedCbs.push(cb)
+}
+
+export function removeSymbolChangedCallback(cb) {
+ symbolChangedCbs = symbolChangedCbs.filter((i)=>i!==cb)
+}
+
+function changeSymbol(symbol) {
+ console.log('tv changeSymbol', symbol)
+ const info = lookupSymbol(symbol.full_name)
+ lastSymbolChangedArgs = info
+ symbolChangedCbs.forEach((cb)=>cb(info))
+}
+
const subscribeEvents = [
'toggle_sidebar', 'indicators_dialog', 'toggle_header', 'edit_object_dialog', 'chart_load_requested',
@@ -51,7 +69,10 @@ function initChart() {
console.log('init chart')
chart = widget.activeChart()
chart.crossHairMoved().subscribe(null, (point)=>setTimeout(()=>handleCrosshairMovement(point),0) )
+ chart.onSymbolChanged().subscribe(null, changeSymbol);
+ changeSymbol(chart.symbolExt())
useChartOrderStore().chartReady = true
+ console.log('chart ready')
}
diff --git a/src/charts/datafeed.js b/src/charts/datafeed.js
index 33c0375..67ddf77 100644
--- a/src/charts/datafeed.js
+++ b/src/charts/datafeed.js
@@ -57,7 +57,7 @@ function addSymbol(p, base, quote, inverted) {
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, inverted,}
+ _symbols[full_name] = {symbol, full_name, description, exchange, type, inverted, base, quote}
indexes[full_name] = {
// key
id: full_name,
@@ -84,7 +84,6 @@ function addSymbol(p, base, quote, inverted) {
// }
async function getAllSymbols() {
-
if (_symbols===null) {
_symbols = {}
for (const t of metadata.t)
@@ -112,6 +111,10 @@ async function getAllSymbols() {
return _symbols
}
+export function lookupSymbol(fullName) {
+ return _symbols[fullName]
+}
+
export default {
onReady: (callback) => {
console.log('[onReady]: Method call');
diff --git a/src/components/ChartPairSelector.vue b/src/components/ChartPairSelector.vue
new file mode 100644
index 0000000..e61a43d
--- /dev/null
+++ b/src/components/ChartPairSelector.vue
@@ -0,0 +1,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/components/NeedsChart.vue b/src/components/NeedsChart.vue
new file mode 100644
index 0000000..3c53b14
--- /dev/null
+++ b/src/components/NeedsChart.vue
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
diff --git a/src/components/PairChoice.vue b/src/components/PairChoice.vue
index 2bef669..5c2efc7 100644
--- a/src/components/PairChoice.vue
+++ b/src/components/PairChoice.vue
@@ -33,7 +33,7 @@
import TokenChoice from "@/components/TokenChoice.vue"
import {useOrderStore, useStore} from "@/store/store";
import RoutePrice from "@/components/RoutePrice.vue";
-import {findRoute} from "@/blockchain/route.js";
+import {findRoute, routeFinder} from "@/blockchain/route.js";
import {SingletonCoroutine, routeInverted} from "@/misc.js";
import {computed, ref} from "vue";
import {queryHelperContract} from "@/blockchain/contract.js";
@@ -46,7 +46,7 @@ const tokenA = computed({
return os.tokenA
},
set(value) {
- if( !os.tokenA || os.tokenA.address !== value.address ) {
+ if( !os.tokenA || os.tokenA.a !== value.a ) {
os.tokenA = value
routeFinder.invoke()
}
@@ -57,7 +57,7 @@ const tokenB = computed({
return os.tokenB
},
set(value) {
- if( !os.tokenB || os.tokenB.address !== value.address ) {
+ if( !os.tokenB || os.tokenB.a !== value.address ) {
os.tokenB = value
routeFinder.invoke()
}
@@ -75,36 +75,6 @@ const routes = computed({
}
})
-async function componentFindRoute() {
- const tokenA = os.tokenA
- const tokenB = os.tokenB
- os.routes = []
- if (!tokenA || !tokenB)
- return
- console.log('finding route', s.chainId.value, tokenA, tokenB)
- os.routesPending = true
- try {
- console.log('getting query helper')
- const helper = await queryHelperContract(s.helper, s.provider)
- if (!helper) {
- console.log('no helper')
- }
- else {
- const result = await findRoute(helper, s.chainId.value, tokenA, tokenB)
- console.log('found route', result)
- os.routes = result
- }
- }
- catch (e) {
- console.log('ignoring routes exception', e)
- }
- finally {
- os.routesPending = false
- }
-}
-
-
-const routeFinder = new SingletonCoroutine(componentFindRoute,10)
routeFinder.invoke()
diff --git a/src/components/chart/ChartOrder.vue b/src/components/chart/ChartOrder.vue
index 4541a07..6b939ec 100644
--- a/src/components/chart/ChartOrder.vue
+++ b/src/components/chart/ChartOrder.vue
@@ -14,8 +14,25 @@
import {useChartOrderStore} from "@/orderbuild.js";
import Toolbar from "@/components/chart/Toolbar.vue";
import BuilderFactory from "@/components/chart/BuilderFactory.vue";
+import {addSymbolChangedCallback, removeSymbolChangedCallback} from "@/charts/chart.js";
+import {onBeforeUnmount} from "vue";
+import {useOrderStore} from "@/store/store.js";
+
+import {routeFinder} from "@/blockchain/route.js";
const co = useChartOrderStore()
+const os = useOrderStore()
+
+function changeSymbol(symbol) {
+ console.log('changeSymbol', symbol)
+ os.tokenA = symbol.base
+ os.tokenB = symbol.quote
+ routeFinder.invoke()
+}
+
+
+const oldSymbolChanged = addSymbolChangedCallback(changeSymbol)
+onBeforeUnmount(() => removeSymbolChangedCallback(changeSymbol) )
diff --git a/src/misc.js b/src/misc.js
index d1304f2..cb1a53b 100644
--- a/src/misc.js
+++ b/src/misc.js
@@ -91,8 +91,8 @@ export function timestamp(date=null) {
export function pairKey(tokenA, tokenB) {
- const token0 = tokenA.address < tokenB.address ? tokenA.address : tokenB.address
- const token1 = tokenA.address > tokenB.address ? tokenA.address : tokenB.address
+ const token0 = tokenA.a < tokenB.a ? tokenA.a : tokenB.a
+ const token1 = tokenA.a > tokenB.a ? tokenA.a : tokenB.a
return [token0, token1];
}
diff --git a/src/orderbuild.js b/src/orderbuild.js
index c999e4e..c09bf40 100644
--- a/src/orderbuild.js
+++ b/src/orderbuild.js
@@ -93,7 +93,7 @@ export function applyLine(tranche, intercept, slope, isMinimum = null) {
const os = useOrderStore()
const route = os.route
const inverted = routeInverted(route)
- const scale = 10 ** (os.tokenA.decimals - os.tokenB.decimals)
+ const scale = 10 ** (os.tokenA.d - os.tokenB.d)
let m = inverted ? -scale / slope : slope / scale
let b = inverted ? scale / intercept : intercept / scale
const cur = b + timestamp() * m
diff --git a/src/routeFinder.js b/src/routeFinder.js
new file mode 100644
index 0000000..e69de29
diff --git a/src/version.js b/src/version.js
index ed94910..fd3b544 100644
--- a/src/version.js
+++ b/src/version.js
@@ -1,5 +1,17 @@
-const versionPromise = fetch('/version.json').then(async (response)=>await response.json())
-const metadataPromise = fetch('/metadata.json').then(async (response)=>await response.json())
+function _json(name) {
+ return async function(response) {
+ try {
+ return await response.json()
+ }
+ catch (e) {
+ console.error(`could not read ${name}`)
+ return null
+ }
+ }
+}
+
+const versionPromise = fetch('/version.json').then(_json('version.json'))
+const metadataPromise = fetch('/metadata.json').then(_json('metadata.json'))
export const version = await versionPromise
console.log('version', version)