196 lines
7.0 KiB
JavaScript
196 lines
7.0 KiB
JavaScript
// Utilities
|
|
import {defineStore} from 'pinia'
|
|
import {knownTokens} from "@/knownTokens.js";
|
|
import {computed, ref} from "vue";
|
|
import {version} from "@/version.js";
|
|
|
|
// USING THE STORE:
|
|
//
|
|
//
|
|
// When defining the store, use Vue script setup syntax, which requires assignment to .value:
|
|
//
|
|
// defineStore('foostore', ()=>{
|
|
// const foo = ref(true)
|
|
// const obj = ref({})
|
|
// function reset() {
|
|
// obj.value = {}
|
|
// foo.value = false
|
|
// }
|
|
// })
|
|
//
|
|
//
|
|
// Then use the store in components:
|
|
//
|
|
// const s = useStore()
|
|
// if( s.foo ) // store variables may be read simply
|
|
// s.reset() // store actions (functions) may be called directly
|
|
// const stuff = [ {}, [], true ]
|
|
// if( s.obj.value in stuff || s.obj.value === {} ) ... // use .value to access the raw object instead of its reference
|
|
|
|
function timestamp() {
|
|
return Math.round(new Date().getTime() / 1000)
|
|
}
|
|
|
|
|
|
const UNKNOWN_PROVIDER = {}
|
|
|
|
|
|
export const useStore = defineStore('app', ()=> {
|
|
const clock = ref(timestamp())
|
|
const nav = ref(false) // controls opening navigation drawer
|
|
|
|
const _chainId = ref(Number(Object.keys(version.chainInfo)[0]))
|
|
const _chainInfo = ref(version.chainInfo)
|
|
|
|
function getTokenList() {
|
|
const chains = _chainId.value in _chainInfo.value && _chainInfo.value[_chainId.value].tokens !== undefined ?
|
|
_chainInfo.value[_chainId.value].tokens : []
|
|
let known = knownTokens[_chainId.value]
|
|
known = known ? Object.values(known) : []
|
|
let extras = extraTokens[_chainId.value]
|
|
extras = extras ? Object.values(extras) : []
|
|
return [...chains, ...known, ...extras]; // put chains first so the Mockcoin pool is automatically selected
|
|
}
|
|
function getTokens() {
|
|
const result = {}
|
|
const all = getTokenList();
|
|
for (const token of all)
|
|
result[token.address] = token
|
|
return result
|
|
}
|
|
const chainId = computed({
|
|
get() {return _chainId.value},
|
|
set(v) {
|
|
console.log('setting app chainid',_chainId.value, v)
|
|
const changed = _chainId.value!==v;
|
|
if (changed) {
|
|
console.log('do set')
|
|
_chainId.value = v
|
|
account.value = null
|
|
}
|
|
if (changed || providerRef.value === null) {
|
|
console.log('invalidating provider')
|
|
providerRef.value = UNKNOWN_PROVIDER
|
|
}
|
|
}
|
|
})
|
|
const chainInfo = computed({
|
|
get() {return _chainInfo.value},
|
|
set(v) {_chainInfo.value=v}
|
|
})
|
|
const chain = computed(() => !_chainId.value ? null : (_chainInfo.value[_chainId.value] || null))
|
|
// this provider is for the app's chainId not the wallet's chainId.
|
|
const providerRef = ref(null)
|
|
const provider = computed(()=>providerRef.value)
|
|
const vaultInitCodeHash = computed(() => !chain.value ? null : chain.value.vaultInitCodeHash)
|
|
const account = ref(null)
|
|
const vaults = ref([])
|
|
const transactionSenders = ref([]) // a list of function(signer) that send transactions
|
|
const errors = ref([])
|
|
const extraTokens = ref({})
|
|
const poolPrices = ref({}) // keyed by [chainId,addr]
|
|
const vaultBalances = ref({}) // indexed by vault addr then by token addr. value is an int
|
|
const orders = ref({}) // indexed by vault value is another dictionary with orderIndex as key and order status values
|
|
|
|
const vault = computed(() => vaults.value.length === 0 ? null : vaults.value[0])
|
|
const balances = computed( () => vault.value === null ? {} : vaultBalances.value[vault] || {} )
|
|
const tokens = computed(getTokens)
|
|
const factory = computed(() => !chain.value ? null : chain.value.factory)
|
|
const helper = computed(() => {console.log('chain helper', chain.value); return !chain.value ? null : chain.value.helper})
|
|
const mockenv = computed(() => !chain.value ? null : chain.value.mockenv)
|
|
const mockCoins = computed(() => !chain.value ? [] : !chain.value.mockCoins ? [] : chain.value.mockCoins)
|
|
|
|
function removeTransactionSender(sender) {
|
|
this.transactionSenders = this.transactionSenders.filter((v) => v !== sender)
|
|
}
|
|
function error(title, text, closeable=true) {
|
|
this.errors.push({title, text, closeable})
|
|
}
|
|
function closeError(title, text) {
|
|
const result = []
|
|
this.errors.forEach((i)=>{if(i.title!==title && i.text!==text) result.push(i)})
|
|
this.errors = result
|
|
}
|
|
function addToken(chainId, info) {
|
|
let extras = this.extraTokens[chainId]
|
|
if (extras === undefined) {
|
|
extras = {}
|
|
this.extraTokens[chainId] = extras
|
|
}
|
|
extras[info.address] = info
|
|
this.extraTokens = extras
|
|
}
|
|
|
|
setInterval(()=>clock.value=timestamp(), 10*1000)
|
|
|
|
return {
|
|
nav, chainId, chainInfo, chain, provider, providerRef, vaultInitCodeHash, account, vaults, transactionSenders,
|
|
errors, extraTokens, poolPrices, vaultBalances, orders, vault, tokens, factory, helper, mockenv, mockCoins,
|
|
removeTransactionSender, error, closeError, addToken, clock, balances,
|
|
}
|
|
})
|
|
|
|
|
|
export const useOrderStore = defineStore('order', ()=> {
|
|
const tokenA = ref(null)
|
|
const tokenB = ref(null)
|
|
|
|
// Order Input Forms
|
|
// const tokenA = ref(null) // defined at top
|
|
// const tokenB = ref(null)
|
|
const buy = ref(true)
|
|
const inverted = ref(false)
|
|
const amount = ref(100) // todo adjust default
|
|
const amountIsTokenA = ref(false) // todo adjust default
|
|
const amountIsTotal = ref(true)
|
|
const slippage = ref(0.10) // in percent units. 1 = 1%. may be null.
|
|
const limitPrice = ref(null)
|
|
const limitPrice2 = ref(null)
|
|
const tranches = ref(3)
|
|
const interval = ref(1)
|
|
const intervalIsTotal = ref(true)
|
|
const timeUnitIndex = ref(0)
|
|
const routes = ref([])
|
|
const routesPending = ref(false)
|
|
const utc = ref(false)
|
|
|
|
const validOrder = computed(() => amount.value > 0 && routes.value.length > 0)
|
|
const route = computed(() => routes.value.length === 0 ? null : routes.value[0])
|
|
const base = computed(() => {
|
|
const token = inverted.value ? tokenB.value : tokenA.value
|
|
return !token ? {} : token
|
|
})
|
|
const quote = computed(() => {
|
|
const token = inverted.value ? tokenA.value : tokenB.value
|
|
return !token ? {} : token
|
|
})
|
|
const pairSymbol = computed(() => base.value?.s + '/' + quote.value?.s)
|
|
const limitIsMinimum = computed(() => !(buy.value ^ inverted.value))
|
|
const amountToken = computed(() => amountIsTokenA.value ? tokenA.value : tokenB.value)
|
|
const amountIsInput = computed(() => amountIsTokenA.value !== buy.value)
|
|
const totalAmount = computed(()=> amountIsTotal.value ? amount.value : amount.value * tranches.value )
|
|
const trancheAmount = computed(()=> amountIsTotal.value ? amount.value / tranches.value : amount.value )
|
|
|
|
function setDefaultTokens(tokens) {
|
|
if( tokens.length > 0 )
|
|
tokenA.value = tokens[0]
|
|
if( tokens.length > 1 )
|
|
tokenB.value = tokens[1]
|
|
}
|
|
|
|
return {
|
|
tokenA, tokenB, buy, inverted, amount, amountIsTokenA, amountIsTotal, slippage, limitPrice, limitPrice2, tranches,
|
|
interval, intervalIsTotal, timeUnitIndex, routes, routesPending, validOrder, route, base, quote, pairSymbol,
|
|
limitIsMinimum, amountToken, amountIsInput, setDefaultTokens, totalAmount, trancheAmount, utc,
|
|
}
|
|
})
|
|
|
|
|
|
export const usePrefStore = defineStore('prefs', ()=> {
|
|
// user preferences
|
|
const inverted = ref({})
|
|
|
|
return {inverted,}
|
|
})
|
|
|