order status updates working

This commit is contained in:
Tim Olson
2023-11-08 23:18:36 -04:00
parent 077e664a30
commit f1bc632074
14 changed files with 259 additions and 21 deletions

20
src/components/Btn.vue Normal file
View 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>

View File

@@ -2,22 +2,121 @@
<v-table>
<thead>
<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>&nbsp;</th> <!-- actions -->
</tr>
</thead>
<tbody>
<tr v-for="order in orders">
<td></td>
<tr v-for="[index, inTokenAddr, outTokenAddr, amount, amountTokenAddr, filled, avgPrice] in orders">
<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>
</tbody>
</v-table>
</template>
<script setup>
import {FixedNumber} from "ethers";
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 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>

View File

@@ -265,7 +265,7 @@ function placeOrder() {
window = duration
duration *= n // duration is the total time for all tranches
} else {
window = duration / n
window = Math.round(duration / n)
}
const oneHundredPercent = 65535n // by contract definition of uint16 fraction
const ceil = oneHundredPercent % BigInt(n) ? 1n : 0n

View File

@@ -23,18 +23,40 @@
</v-card-text>
</PhoneCard>
-->
<v-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>
<phone-card v-if="s.vaults.length<=num">
<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>
<!-- 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-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">
<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 -->
-->
<!-- User-actioned but dexorder executed
<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-text v-if="empty">
<p>There are no funds currently in your vault.</p>
<p>Send tokens to the address above to fund your vault.</p>
<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-item v-if="!empty">
<v-table>
@@ -61,9 +83,12 @@
import {useStore} from "@/store/store.js";
import {computed, defineAsyncComponent, ref} from "vue";
import {vaultAddress} from "@/blockchain/contract.js";
import {ensureVault} from "@/blockchain/wallet.js";
import CopyButton from "@/components/CopyButton.vue";
import NeedsProvider from "@/components/NeedsProvider.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 s = useStore()
@@ -86,8 +111,16 @@ function onWithdraw(addr) {
withdrawToken.value = token
withdrawShow.value = true
}
// todo remove automatic vault creation for Alpha 2
if(props.num===0 && !s.vault)
ensureVault()
</script>
<style scoped lang="scss">
@use "../styles/vars" as *;
p {
margin-top: 1.5em;
}
</style>