// 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,} })