order status updates working
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
"name": "dexorder",
|
"name": "dexorder",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
|
|||||||
11
src/blockchain/common.js
Normal file
11
src/blockchain/common.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
export function applyFills( orderStatus, filled ) {
|
||||||
|
console.log('apply fills', orderStatus, filled)
|
||||||
|
orderStatus[4] = filled[0][0]
|
||||||
|
orderStatus[5] = filled[0][1]
|
||||||
|
for( const i in filled[1] ) {
|
||||||
|
const {filledIn, filledOut} = filled[1][i]
|
||||||
|
orderStatus[6][i] = filledIn
|
||||||
|
orderStatus[7][i] = filledOut
|
||||||
|
}
|
||||||
|
console.log('applied fills', orderStatus)
|
||||||
|
}
|
||||||
@@ -3,6 +3,19 @@ import {useStore} from "@/store/store.js";
|
|||||||
import {erc20Abi} from "@/blockchain/abi.js";
|
import {erc20Abi} from "@/blockchain/abi.js";
|
||||||
import {ethers} from "ethers";
|
import {ethers} from "ethers";
|
||||||
|
|
||||||
|
|
||||||
|
// synchronous version may return null but will trigger a lookup
|
||||||
|
export function token(addr) {
|
||||||
|
const s = useStore()
|
||||||
|
if( !(addr in s.tokens) ) {
|
||||||
|
getToken(addr)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return s.tokens[addr]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// async version doesnt return until it has a token value
|
||||||
export async function getToken(addr) {
|
export async function getToken(addr) {
|
||||||
const s = useStore()
|
const s = useStore()
|
||||||
if (!(addr in s.tokens))
|
if (!(addr in s.tokens))
|
||||||
|
|||||||
@@ -88,14 +88,27 @@ export async function connectWallet() {
|
|||||||
|
|
||||||
const pendingOrders = []
|
const pendingOrders = []
|
||||||
|
|
||||||
|
|
||||||
|
export function ensureVault() {
|
||||||
|
const s = useStore()
|
||||||
|
if( !s.chain ) {
|
||||||
|
console.log('cannot create vault: no chain selected')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if( !s.account ) {
|
||||||
|
console.log('cannot create vault: no account logged in')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
socket.emit('ensureVault', s.chainId, s.account, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export async function pendOrder(order) {
|
export async function pendOrder(order) {
|
||||||
console.log('order', JSON.stringify(order))
|
console.log('order', JSON.stringify(order))
|
||||||
const s = useStore()
|
const s = useStore()
|
||||||
const signer = await s.provider.getSigner()
|
|
||||||
if (!s.vaults.length) {
|
if (!s.vaults.length) {
|
||||||
pendingOrders.push(order)
|
pendingOrders.push(order)
|
||||||
const owner = await signer.getAddress();
|
ensureVault()
|
||||||
socket.emit('ensureVault', s.chainId, owner, 0)
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const vault = s.vaults[0];
|
const vault = s.vaults[0];
|
||||||
|
|||||||
20
src/components/Btn.vue
Normal file
20
src/components/Btn.vue
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<template>
|
||||||
|
<v-btn variant="outlined">
|
||||||
|
<v-icon v-if="icon" :icon="icon" :color="color"></v-icon>
|
||||||
|
<slot/>
|
||||||
|
</v-btn>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {useStore} from "@/store/store";
|
||||||
|
import {useAttrs} from "vue";
|
||||||
|
|
||||||
|
const s = useStore()
|
||||||
|
const props = defineProps(['icon', 'color'])
|
||||||
|
const attrs = useAttrs()
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
@use "src/styles/vars" as *;
|
||||||
|
</style>
|
||||||
@@ -2,22 +2,121 @@
|
|||||||
<v-table>
|
<v-table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th></th>
|
<th>#</th>
|
||||||
|
<th>Buy Token</th>
|
||||||
|
<th>Sell Token</th>
|
||||||
|
<th>Amount</th>
|
||||||
|
<th>Filled</th>
|
||||||
|
<th>Remaining</th>
|
||||||
|
<th>Average Price</th>
|
||||||
|
<th> </th> <!-- actions -->
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="order in orders">
|
<tr v-for="[index, inTokenAddr, outTokenAddr, amount, amountTokenAddr, filled, avgPrice] in orders">
|
||||||
<td></td>
|
<td>{{parseInt(index)+1}}</td>
|
||||||
|
<td>{{tokenSymbol(inTokenAddr)}}</td>
|
||||||
|
<td>{{tokenSymbol(outTokenAddr)}}</td>
|
||||||
|
<td>{{tokenAmount(amountTokenAddr, amount)}}</td>
|
||||||
|
<td>{{tokenAmount(amountTokenAddr, filled)}}</td>
|
||||||
|
<td>{{tokenAmount(amountTokenAddr, amount-filled)}}</td>
|
||||||
|
<td>
|
||||||
|
{{pairPrice(inTokenAddr, outTokenAddr, vaultAddr, index, avgPrice)}}
|
||||||
|
<btn v-if="pairPrice(inTokenAddr, outTokenAddr, vaultAddr, index, avgPrice)!==''" size="small"
|
||||||
|
@click="inverted[[vaultAddr,index]] = !inverted[[vaultAddr,index]]">
|
||||||
|
{{pair(inTokenAddr, outTokenAddr, vaultAddr,index)}}
|
||||||
|
</btn>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</v-table>
|
</v-table>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import {FixedNumber} from "ethers";
|
||||||
import {useStore} from "@/store/store";
|
import {useStore} from "@/store/store";
|
||||||
|
import {computed, reactive} from "vue";
|
||||||
|
import {token} from "@/blockchain/token.js";
|
||||||
|
import Btn from "@/components/Btn.vue"
|
||||||
|
|
||||||
const s = useStore()
|
const s = useStore()
|
||||||
const orders = 0; // todo tim here
|
const props = defineProps(['vault'])
|
||||||
|
const vaultAddr = computed(()=>props.vault?props.vault:s.vault)
|
||||||
|
const inverted = reactive({})
|
||||||
|
|
||||||
|
function tokenSymbol(addr) {
|
||||||
|
const t = token(addr)
|
||||||
|
return t ? t.symbol : addr
|
||||||
|
}
|
||||||
|
|
||||||
|
function tokenAmount(tokenAddr, amount) {
|
||||||
|
const t = token(tokenAddr)
|
||||||
|
if( !t )
|
||||||
|
return ''
|
||||||
|
const amt = FixedNumber.fromValue(amount, t.decimals, {width:256, decimals:t.decimals, signed:false})
|
||||||
|
return `${amt} ${t.symbol}`
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo create a Price component that keeps inversion flags in the store and defaults to stablecoins as the quote
|
||||||
|
function pairPrice(inTokenAddr, outTokenAddr, vaultAddr, index, price) {
|
||||||
|
if( price === null )
|
||||||
|
return ''
|
||||||
|
const inToken = token(inTokenAddr)
|
||||||
|
const outToken = token(outTokenAddr)
|
||||||
|
if( !inToken || !outToken )
|
||||||
|
return ''
|
||||||
|
|
||||||
|
console.log('inout tokens', inToken, outToken)
|
||||||
|
console.log('price1', price, outToken.decimals, inToken.decimals)
|
||||||
|
const decimals = outToken.decimals-inToken.decimals
|
||||||
|
if( decimals > 0 )
|
||||||
|
price /= 10 ** decimals
|
||||||
|
else
|
||||||
|
price *= 10 ** -decimals
|
||||||
|
console.log('price2', price)
|
||||||
|
const invertedKey = [vaultAddr,index];
|
||||||
|
if( !(invertedKey in inverted) ) {
|
||||||
|
// todo prefer stablecoins as the quote asset
|
||||||
|
inverted[invertedKey] = false
|
||||||
|
}
|
||||||
|
const inv = inverted[invertedKey]
|
||||||
|
return inv ? (1 / price).toPrecision(5) : price.toPrecision(5)
|
||||||
|
}
|
||||||
|
|
||||||
|
function pair(inTokenAddr, outTokenAddr, vaultAddr, index) {
|
||||||
|
const inToken = token(inTokenAddr)
|
||||||
|
const outToken = token(outTokenAddr)
|
||||||
|
return !inToken || !outToken ? null : inverted[[vaultAddr,index]] ?
|
||||||
|
outToken.symbol+'/'+inToken.symbol : inToken.symbol+'/'+outToken.symbol
|
||||||
|
}
|
||||||
|
|
||||||
|
const orders = computed(()=>{
|
||||||
|
if( !(vaultAddr.value in s.orders) )
|
||||||
|
return {}
|
||||||
|
const result = []
|
||||||
|
for( const [index,status] of Object.entries(s.orders[vaultAddr.value]) ) {
|
||||||
|
console.log('order status', status)
|
||||||
|
// [index, symbolA, symbolB, amount, amountSymbol, filled]
|
||||||
|
const inTokenAddr = status[0][0]
|
||||||
|
const outTokenAddr = status[0][1]
|
||||||
|
const amountIsInput = !!(status[0][4])
|
||||||
|
const amountTokenAddr = amountIsInput ? inTokenAddr : outTokenAddr
|
||||||
|
console.log('getamount', status[0][3])
|
||||||
|
const amount = status[0][3]
|
||||||
|
console.log('amount', amount)
|
||||||
|
console.log('getfilled', amountIsInput ? status[4] : status[5])
|
||||||
|
const filled = amountIsInput ? status[4] : status[5]
|
||||||
|
console.log('filled', filled)
|
||||||
|
const amountIn = BigInt(status[4])
|
||||||
|
const amountOut = BigInt(status[5])
|
||||||
|
const fmtX18 = {decimals:18, width: 256, signed:false};
|
||||||
|
const avg = !amountIn || !amountOut ? null :
|
||||||
|
FixedNumber.fromValue(status[5],0, fmtX18).div(FixedNumber.fromValue(status[4], 0, fmtX18))
|
||||||
|
result.push([index, inTokenAddr, outTokenAddr, amount, amountTokenAddr, filled, avg])
|
||||||
|
}
|
||||||
|
console.log('result', result)
|
||||||
|
return result
|
||||||
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -265,7 +265,7 @@ function placeOrder() {
|
|||||||
window = duration
|
window = duration
|
||||||
duration *= n // duration is the total time for all tranches
|
duration *= n // duration is the total time for all tranches
|
||||||
} else {
|
} else {
|
||||||
window = duration / n
|
window = Math.round(duration / n)
|
||||||
}
|
}
|
||||||
const oneHundredPercent = 65535n // by contract definition of uint16 fraction
|
const oneHundredPercent = 65535n // by contract definition of uint16 fraction
|
||||||
const ceil = oneHundredPercent % BigInt(n) ? 1n : 0n
|
const ceil = oneHundredPercent % BigInt(n) ? 1n : 0n
|
||||||
|
|||||||
@@ -23,18 +23,40 @@
|
|||||||
</v-card-text>
|
</v-card-text>
|
||||||
</PhoneCard>
|
</PhoneCard>
|
||||||
-->
|
-->
|
||||||
<v-card v-if="s.vaults.length<=num">
|
<phone-card v-if="s.vaults.length<=num">
|
||||||
<v-card-title><v-icon icon="mdi-safe-square-outline" size="small" color="red"/> No Vault Yet</v-card-title>
|
<v-card-title><v-icon icon="mdi-safe-square" size="small" color="grey-darken-1"/> Create a Dexorder Vault</v-card-title>
|
||||||
<v-card-text v-if="num!==0"><!--todo-->Multiple vaults are not yet supported</v-card-text>
|
<v-card-text v-if="num!==0"><!--todo-->Multiple vaults are not yet supported</v-card-text>
|
||||||
|
<!-- todo restore the vault-on-order approach for public beta
|
||||||
<v-card-text v-if="num===0">Create an order first, then your vault account will appear here to accept a deposit of trading funds.</v-card-text>
|
<v-card-text v-if="num===0">Create an order first, then your vault account will appear here to accept a deposit of trading funds.</v-card-text>
|
||||||
<v-card-actions><v-btn prepend-icon="mdi-plus" text="Create Order" @click="$router.push('/twap')"/></v-card-actions>
|
<v-card-actions><v-btn prepend-icon="mdi-plus" text="Create Order" @click="$router.push('/twap')"/></v-card-actions>
|
||||||
</v-card>
|
-->
|
||||||
<v-card v-if="s.vaults.length>num">
|
<!-- User-actioned but dexorder executed
|
||||||
<v-card-title><v-icon icon="mdi-safe-square-outline" size="small"/> My Vault {{s.vaults.length>1?'#'+(num+1):''}}</v-card-title> <!-- todo vault nicknames -->
|
<v-card-text v-if="num===0">
|
||||||
|
Your vault is a smart contract that securely holds your funds plus any orders you place. When your order
|
||||||
|
conditions are met, Dexorder creates a blockchain transaction for <code>vault.execute()</code>,
|
||||||
|
asking your vault to the order. Your vault then checks that order against the
|
||||||
|
current blockchain time and pool price, and only trades if everything looks good.
|
||||||
|
|
||||||
|
Start placing dexorders by clicking the button below to create your own personal Vault!
|
||||||
|
</v-card-text>
|
||||||
|
<v-card-actions><btn icon="mdi-safe-square" color="grey-darken-1" text="Create Vault" @click="ensureVault"/></v-card-actions>
|
||||||
|
-->
|
||||||
|
<v-card-text v-if="num===0">
|
||||||
|
Please wait while your vault is being created. This should only take a few seconds.
|
||||||
|
</v-card-text>
|
||||||
|
</phone-card>
|
||||||
|
<v-card v-if="s.vaults.length>num" :class="empty?'maxw':''">
|
||||||
|
<v-card-title><v-icon icon="mdi-safe-square" color="grey-darken-2" size="small"/> My Vault {{s.vaults.length>1?'#'+(num+1):''}}</v-card-title> <!-- todo vault nicknames -->
|
||||||
<v-card-subtitle v-if="exists" class="overflow-x-hidden"><copy-button :text="addr"/>{{addr}}</v-card-subtitle>
|
<v-card-subtitle v-if="exists" class="overflow-x-hidden"><copy-button :text="addr"/>{{addr}}</v-card-subtitle>
|
||||||
<v-card-text v-if="empty">
|
<v-card-text v-if="empty">
|
||||||
<p>There are no funds currently in your vault.</p>
|
<p>
|
||||||
<p>Send tokens to the address above to fund your vault.</p>
|
Your vault is a smart contract that securely holds your funds plus any orders you place. When your order
|
||||||
|
conditions are met, Dexorder creates a blockchain transaction for <code>vault.execute()</code>,
|
||||||
|
asking your vault to the order. Your vault then checks that order against the
|
||||||
|
current blockchain time and pool price, and only trades if everything looks good.
|
||||||
|
</p>
|
||||||
|
<p v-if="!s.mockenv">There are no funds currently in your vault. Send tokens to the address above to fund your vault.</p>
|
||||||
|
<p v-if="s.mockenv">There are no funds currently in your vault. Use the faucet below to mint some fake coins into your vault.</p>
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
<v-card-item v-if="!empty">
|
<v-card-item v-if="!empty">
|
||||||
<v-table>
|
<v-table>
|
||||||
@@ -61,9 +83,12 @@
|
|||||||
import {useStore} from "@/store/store.js";
|
import {useStore} from "@/store/store.js";
|
||||||
import {computed, defineAsyncComponent, ref} from "vue";
|
import {computed, defineAsyncComponent, ref} from "vue";
|
||||||
import {vaultAddress} from "@/blockchain/contract.js";
|
import {vaultAddress} from "@/blockchain/contract.js";
|
||||||
|
import {ensureVault} from "@/blockchain/wallet.js";
|
||||||
import CopyButton from "@/components/CopyButton.vue";
|
import CopyButton from "@/components/CopyButton.vue";
|
||||||
import NeedsProvider from "@/components/NeedsProvider.vue";
|
import NeedsProvider from "@/components/NeedsProvider.vue";
|
||||||
import Withdraw from "@/components/Withdraw.vue";
|
import Withdraw from "@/components/Withdraw.vue";
|
||||||
|
import PhoneCard from "@/components/PhoneCard.vue";
|
||||||
|
import Btn from "@/components/Btn.vue";
|
||||||
|
|
||||||
const TokenRow = defineAsyncComponent(()=>import('./TokenRow.vue'))
|
const TokenRow = defineAsyncComponent(()=>import('./TokenRow.vue'))
|
||||||
const s = useStore()
|
const s = useStore()
|
||||||
@@ -86,8 +111,16 @@ function onWithdraw(addr) {
|
|||||||
withdrawToken.value = token
|
withdrawToken.value = token
|
||||||
withdrawShow.value = true
|
withdrawShow.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo remove automatic vault creation for Alpha 2
|
||||||
|
if(props.num===0 && !s.vault)
|
||||||
|
ensureVault()
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@use "../styles/vars" as *;
|
@use "../styles/vars" as *;
|
||||||
|
p {
|
||||||
|
margin-top: 1.5em;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<v-chip text="ALPHA" size="x-small" color="red" class="mx-1"/>
|
<v-chip text="ALPHA" size="x-small" color="red" class="mx-1"/>
|
||||||
</v-app-bar-title>
|
</v-app-bar-title>
|
||||||
|
|
||||||
<v-btn icon="mdi-safe-square-outline" text="Vault" @click="$router.push('/vault')"></v-btn>
|
<v-btn icon="mdi-safe-square" color="grey-darken-2" text="Vault" @click="$router.push('/vault')"></v-btn>
|
||||||
<v-btn icon="mdi-swap-horizontal-circle-outline" text="New Order" @click="$router.push('/twap')"></v-btn>
|
<v-btn icon="mdi-swap-horizontal-circle-outline" text="New Order" @click="$router.push('/twap')"></v-btn>
|
||||||
<v-btn icon="mdi-menu" text="Order Status" @click="$router.push('/orders')"></v-btn>
|
<v-btn icon="mdi-menu" text="Order Status" @click="$router.push('/orders')"></v-btn>
|
||||||
|
|
||||||
|
|||||||
@@ -12,19 +12,29 @@ import 'vuetify/styles'
|
|||||||
import { createVuetify } from 'vuetify'
|
import { createVuetify } from 'vuetify'
|
||||||
|
|
||||||
// https://vuetifyjs.com/en/introduction/why-vuetify/#feature-guides
|
// https://vuetifyjs.com/en/introduction/why-vuetify/#feature-guides
|
||||||
|
const black = '#333'
|
||||||
export default createVuetify({
|
export default createVuetify({
|
||||||
theme: {
|
theme: {
|
||||||
themes: {
|
themes: {
|
||||||
light: {
|
light: {
|
||||||
colors: {
|
colors: {
|
||||||
background: '#fffefd',
|
background: '#fdfffe',
|
||||||
surface: '#fffefd',
|
surface: '#fdfffe',
|
||||||
primary: '#1A6CAB',
|
// primary: '#1A6CAB',
|
||||||
|
primary: '#00CC33',
|
||||||
// secondary: '#59B8FF',
|
// secondary: '#59B8FF',
|
||||||
success: '#00CC33',
|
success: '#00CC33',
|
||||||
// info: '#fba92c',
|
// info: '#fba92c',
|
||||||
warning: '#ffcc00',
|
warning: '#ffcc00',
|
||||||
error: '#CC0033',
|
error: '#CC0033',
|
||||||
|
"on-background": black,
|
||||||
|
"on-surface": black,
|
||||||
|
"on-primary": black,
|
||||||
|
"on-secondary": black,
|
||||||
|
"on-success": black,
|
||||||
|
"on-info": black,
|
||||||
|
"on-warning": black,
|
||||||
|
"on-error": black,
|
||||||
},
|
},
|
||||||
dark: false,
|
dark: false,
|
||||||
variables: {},
|
variables: {},
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import {io} from "socket.io-client";
|
|||||||
import {useStore} from "@/store/store.js";
|
import {useStore} from "@/store/store.js";
|
||||||
import {flushOrders, onChainChanged} from "@/blockchain/wallet.js";
|
import {flushOrders, onChainChanged} from "@/blockchain/wallet.js";
|
||||||
import {ethers} from "ethers";
|
import {ethers} from "ethers";
|
||||||
|
import {applyFills} from "@/blockchain/common.js";
|
||||||
|
|
||||||
export const socket = io(import.meta.env.VITE_WS_URL || undefined, {transports: ["websocket"]})
|
export const socket = io(import.meta.env.VITE_WS_URL || undefined, {transports: ["websocket"]})
|
||||||
|
|
||||||
@@ -59,16 +60,42 @@ socket.on('vaults', (chainId, owner, vaults)=>{
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
socket.on( 'o', (chainId, vault, orderIndex, status)=>{
|
|
||||||
|
function handleOrderStatus(chainId, vault, orderIndex, status) {
|
||||||
const s = useStore()
|
const s = useStore()
|
||||||
if( s.chainId !== chainId )
|
if( s.chainId !== chainId )
|
||||||
return
|
return
|
||||||
console.log('o', chainId, vault, orderIndex, status)
|
console.log('o', chainId, vault, orderIndex, status)
|
||||||
|
const orders = s.orders
|
||||||
|
if( !(vault in orders) )
|
||||||
|
orders[vault] = {}
|
||||||
|
orders[vault][orderIndex] = status
|
||||||
|
s.orders = orders
|
||||||
|
}
|
||||||
|
|
||||||
|
socket.on('os', (chainId, vault, orders) => {
|
||||||
|
console.log('os', orders)
|
||||||
|
for( const [orderIndex, status] of orders )
|
||||||
|
handleOrderStatus(chainId, vault, orderIndex, status)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
socket.on( 'o', handleOrderStatus)
|
||||||
|
|
||||||
socket.on( 'of', (chainId, vault, orderIndex, fills)=>{
|
socket.on( 'of', (chainId, vault, orderIndex, fills)=>{
|
||||||
const s = useStore()
|
const s = useStore()
|
||||||
if( s.chainId !== chainId )
|
if( s.chainId !== chainId )
|
||||||
return
|
return
|
||||||
console.log('of', chainId, vault, orderIndex, fills)
|
console.log('of', chainId, vault, orderIndex, fills)
|
||||||
|
const orders = s.orders
|
||||||
|
if( !(vault in orders) ) {
|
||||||
|
console.log('warning: got fill on an order in an unknown vault')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if( !(orderIndex in orders[vault]) ) {
|
||||||
|
console.log(`warning: orderIndex ${orderIndex} missing from vault ${vault}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const order = orders[vault][orderIndex]
|
||||||
|
applyFills(order, fills)
|
||||||
|
orders[vault][orderIndex] = order
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ export const useStore = defineStore('app', {
|
|||||||
extraTokens: {},
|
extraTokens: {},
|
||||||
poolPrices: {},
|
poolPrices: {},
|
||||||
vaultBalances: {}, // indexed by vault addr then by token addr. value is an int
|
vaultBalances: {}, // indexed by vault addr then by token addr. value is an int
|
||||||
|
orders: {}, // indexed by vault, value is another dictionary with orderIndex as key and order status values
|
||||||
}),
|
}),
|
||||||
getters: {
|
getters: {
|
||||||
vault: (s)=>s.vaults.length===0 ? null : s.vaults[0],
|
vault: (s)=>s.vaults.length===0 ? null : s.vaults[0],
|
||||||
|
|||||||
@@ -36,6 +36,10 @@
|
|||||||
.v-text-field.text-end input {
|
.v-text-field.text-end input {
|
||||||
text-align: end;
|
text-align: end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.maxw {
|
||||||
|
max-width: v.$card-maxw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.uniswap-color {
|
.uniswap-color {
|
||||||
|
|||||||
@@ -1,9 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<orders/>
|
<needs-provider>
|
||||||
|
<needs-signer>
|
||||||
|
<orders/>
|
||||||
|
</needs-signer>
|
||||||
|
</needs-provider>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import Orders from "@/components/Orders.vue";
|
import Orders from "@/components/Orders.vue";
|
||||||
|
import NeedsSigner from "@/components/NeedsSigner.vue";
|
||||||
|
import NeedsProvider from "@/components/NeedsProvider.vue";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
Reference in New Issue
Block a user