order detail foldout

This commit is contained in:
Tim Olson
2023-12-09 00:12:24 -04:00
parent aa731d678e
commit 7e33ffba76
5 changed files with 88 additions and 36 deletions

View File

@@ -6,6 +6,9 @@ export function encodeIEE754(value) {
}
export function decodeIEE754(buffer) {
return new DataView(buffer).getFloat32(0, false);
export function decodeIEE754(value) {
const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);
view.setUint32(0, value, false)
return view.getFloat32(0, false)
}

View File

@@ -1,5 +1,5 @@
import {uint32max, uint64max} from "@/misc.js";
import {encodeIEE754} from "@/blockchain/common.js";
import {decodeIEE754, encodeIEE754} from "@/blockchain/common.js";
export const MAX_FRACTION = 65535;
export const NO_CHAIN = uint64max;
@@ -177,6 +177,10 @@ export function parseTranche(tranche) {
maxIntercept,
maxSlope,
] = tranche
minIntercept = decodeIEE754(minIntercept)
minSlope = decodeIEE754(minSlope)
maxIntercept = decodeIEE754(maxIntercept)
maxSlope = decodeIEE754(maxSlope)
return {
fraction, startTimeIsRelative, endTimeIsRelative, minIsBarrier, maxIsBarrier, marketOrder,
startTime, endTime, minIntercept, minSlope, maxIntercept, maxSlope,

View File

@@ -1,5 +1,6 @@
<template>
<v-data-table :headers="datatableHeaders" :items="orders" item-value="index" item-selectable="selectable" :show-select="true" :show-expand="true">
<v-data-table :headers="datatableHeaders" :items="orders" item-value="index"
item-selectable="selectable" :show-select="false" :show-expand="true">
<template v-slot:item.start="{ value }">{{dateString(value)}}</template>
<template v-slot:item.input="{ item }">
<suspense><token-amount :addr="item.order.tokenIn" :amount="item.order.amountIsInput ? item.order.amount : null"/></suspense>
@@ -14,8 +15,8 @@
<suspense><token-amount :addr="item.amountToken" :amount="item.filled"/></suspense>
</template>
<template v-slot:item.avg="{ item }">
{{pairPrice(item.order.tokenIn, item.order.tokenOut, vaultAddr, item.index, item.avg)}}
<btn v-if="pairPrice(item.order.tokenIn, item.order.tokenOut, vaultAddr, item.index, item.avg)!==''" size="small"
{{pairPrice(item.order.tokenIn, item.order.tokenOut, vaultAddr, item.avg)}}
<btn v-if="pairPrice(item.order.tokenIn, item.order.tokenOut, vaultAddr, item.avg)!==''" size="small"
variant="plain"
@click="inverted[[vaultAddr,item.index]] = !inverted[[vaultAddr,item.index]]">
{{pair(item.order.tokenIn, item.order.tokenOut, vaultAddr, item.index)}}
@@ -31,9 +32,45 @@
<v-chip v-if="item.state===OrderState.Expired" prepend-icon="mdi-progress-check" color="grey-darken-1">Expired</v-chip>
<v-chip v-if="item.state===OrderState.Underfunded" prepend-icon="mdi-alert" color="warning">Underfunded</v-chip>
</template>
<template v-slot:item.action="{ item }">
<template v-slot:item.action="{item}">
<btn v-if="item.state===OrderState.Open" icon="mdi-cancel" color="red" @click="cancelOrder(vaultAddr,item.index)">Cancel</btn>
</template>
<template v-slot:expanded-row="{item}">
<tr>
<td colspan="100">
<v-table>
<!--
<thead>
<tr>
<th></th>
<th>Filled</th>
<th></th>
</tr>
</thead>
-->
<tbody>
<tr v-for="(t, i) in item.order.tranches">
<td>Tranche {{ i + 1 }}</td>
<td>
<suspense>
<span>
<token-amount :addr="item.amountToken" :amount="item.trancheFilled[i]" :raw="true"/>
/
<token-amount :addr="item.amountToken" :amount="item.order.amount*BigInt(t.fraction)/65535n"/>
</span>
</suspense>
</td>
<td>
{{describeTrancheTime(item,t)}}
{{describeTrancheLine(item,true,t.minIntercept,t.minSlope)}}
{{describeTrancheLine(item,false,t.maxIntercept,t.maxSlope)}}
</td>
</tr>
</tbody>
</v-table>
</td>
</tr>
</template>
</v-data-table>
</template>
@@ -53,28 +90,9 @@ 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) {
if( !tokenAddr || !amount )
return ''
console.log('token amount', tokenAddr, amount)
if( typeof tokenAddr !== 'string' )
throw Error('broke')
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) {
function pairPrice(inTokenAddr, outTokenAddr, vaultAddr, price) {
if( price === null )
return ''
const inToken = token(inTokenAddr)
@@ -87,7 +105,9 @@ function pairPrice(inTokenAddr, outTokenAddr, vaultAddr, index, price) {
price /= 10 ** decimals
else
price *= 10 ** -decimals
const invertedKey = [vaultAddr,index];
const token0 = inTokenAddr < outTokenAddr ? inTokenAddr : outTokenAddr
const token1 = inTokenAddr > outTokenAddr ? inTokenAddr : outTokenAddr
const invertedKey = [token0, token1];
if( !(invertedKey in inverted) ) {
// todo prefer stablecoins as the quote asset
inverted[invertedKey] = false
@@ -107,7 +127,6 @@ function pair(inTokenAddr, outTokenAddr, vaultAddr, index) {
// <thead>
// <tr>
// <th className="num d-none d-md-table-cell">Date</th>
// <!-- todo placement date instead -->
// <th className="token d-none d-sm-table-cell">Input</th>
// <th className="token d-none d-sm-table-cell">Output</th>
// <th className="amount">Remaining</th>
@@ -173,19 +192,18 @@ const orders = computed(()=>{
// ]
const result = []
if( vaultAddr.value in s.orders ) {
for (const [index, status] of Object.entries(s.orders[vaultAddr.value]).reverse()) {
const st = {...status}
console.log('order status', st)
const o = {...st.order}
st.order = o
console.log('order status', st)
result.push(st)
st.index = parseInt(index)
o.tranches = o.tranches.map((tranche)=>{
const t = {...tranche}
t.startTime = t.startTimeIsRelative ? intervalString(t.startTime) : dateString(t.startTime)
t.endTime = t.endTimeIsRelative ? intervalString(t.endTime) : dateString(t.endTime)
// t.startTime = t.startTimeIsRelative ? intervalString(t.startTime) : dateString(t.startTime)
// t.endTime = t.endTimeIsRelative ? intervalString(t.endTime) : dateString(t.endTime)
return t
})
const fmtX18 = {decimals: 18, width: 256, signed: false};
@@ -207,6 +225,33 @@ const orders = computed(()=>{
return result
})
function describeTrancheTime(st, t) {
let result = ''
if( t.minIsBarrier || t.maxIsBarrier )
return 'barrier'
if( t.startTime > 0 ) {
const started = t.startTimeIsRelative ? st.start + t.startTime : t.startTime
console.log('started', started, st.start, t.startTime)
result += started*1000 < Date.now() ? 'Activated ' : 'Activates '
result += dateString(started) + ' '
}
if( t.endTime < 4294967295 ) {
const ended = t.endTimeIsRelative ? st.start + t.endTime : t.endTime
result += ended*1000 < Date.now() ? 'Expired ' : 'Expires '
result += dateString(ended)
}
console.log('tt', st, t)
return result
}
function describeTrancheLine(st, isMin, b, m) {
if( b===0 && m===0 ) return ''
// todo slopes
console.log('tranche line', isMin, b, m)
// todo make this a PairPrice
return (isMin === st.order.amountIsInput ? 'dont-chase ' : 'limit ') + pairPrice(st.order.tokenIn, st.order.tokenOut, s.vault, b)
}
</script>
<style scoped lang="scss">

View File

@@ -1,5 +1,5 @@
<template>
<span>{{fmtAmount}} {{ token.symbol || '' }}</span>
<span>{{fmtAmount}} {{ raw ? '' : (token.symbol || '') }}</span>
</template>
<script setup>
@@ -9,7 +9,7 @@ import {FixedNumber} from "ethers";
import {computed, ref} from "vue";
const s = useStore()
const props = defineProps(['addr', 'amount'])
const props = defineProps(['addr', 'amount', 'raw'])
const token = await getToken(props.addr)
const fmtAmount = computed(() => {
if( props.amount === null || props.amount === undefined )

View File

@@ -76,4 +76,4 @@ const _dateFormat = new Intl.DateTimeFormat( undefined, {dateStyle: 'medium', ti
export function dateString(seconds) {
const date = new Date(seconds*1000)
return _dateFormat.format(date)
}
}