improved order statuses

This commit is contained in:
Tim Olson
2023-11-09 23:23:04 -04:00
parent f1bc632074
commit a41ca81ab2
9 changed files with 103 additions and 38 deletions

View File

@@ -36,9 +36,7 @@ export async function poolContract(addr) {
return contractOrNull(addr, uniswapV3PoolAbi, s.provider) return contractOrNull(addr, uniswapV3PoolAbi, s.provider)
} }
export async function vaultContract(num, signer) { export async function vaultContract(owner, num, provider) {
const s = useStore() const addr = vaultAddress(owner, num)
if( num >= s.vaults.length ) return new ethers.Contract(addr, vaultAbi, provider)
return null
return contractOrNull(s.vaults[num], vaultAbi, signer)
} }

View File

@@ -1,7 +1,7 @@
import {ethers} from "ethers"; import {ethers} from "ethers";
import {setProvider, useStore} from "@/store/store"; import {setProvider, useStore} from "@/store/store";
import {socket} from "@/socket.js"; import {socket} from "@/socket.js";
import {contractOrNull} from "@/blockchain/contract.js"; import {contractOrNull, vaultAddress} from "@/blockchain/contract.js";
import {vaultAbi} from "@/blockchain/abi.js"; import {vaultAbi} from "@/blockchain/abi.js";
@@ -29,6 +29,14 @@ function changeAccounts(accounts) {
else { else {
const store = useStore() const store = useStore()
store.account = accounts[0].address store.account = accounts[0].address
if( pendingOrders.length ) {
if( store.vault )
flushOrders()
else
ensureVault()
}
else
discoverVaults()
flushTransactions() flushTransactions()
socket.emit('address', store.chainId, accounts[0].address) socket.emit('address', store.chainId, accounts[0].address)
} }
@@ -86,7 +94,39 @@ export async function connectWallet() {
await s.provider.getSigner() await s.provider.getSigner()
} }
const pendingOrders = [] let pendingOrders = []
function discoverVaults() {
const s = useStore()
const owner = s.account
_discoverVaults(owner).then((result)=>{
if( s.account === owner ) { // double-check the account since it could have changed during our await
s.vaults = result
if( result.length && pendingOrders.length )
flushOrders(result[0])
}
})
}
async function _discoverVaults(owner) {
const result = []
// todo multi-vault scan
const addr = vaultAddress(owner, 0)
const s = useStore()
const vault = new ethers.Contract(addr, vaultAbi, s.provider)
let version = -1
try {
version = await vault.version();
if( version === 1 )
result.push(addr)
else
console.error(`bad vault version ${version}`)
}
catch (e) {
}
return result
}
export function ensureVault() { export function ensureVault() {
@@ -120,6 +160,8 @@ export async function pendOrder(order) {
export function flushOrders(vault) { export function flushOrders(vault) {
for( const order of pendingOrders ) for( const order of pendingOrders )
pendOrderAsTransaction(vault, order) pendOrderAsTransaction(vault, order)
pendingOrders = []
flushTransactions()
} }

View File

@@ -1,7 +1,7 @@
<template> <template>
<phone-card v-if="s.mockenv && s.vault"> <phone-card v-if="s.mockenv && s.vault">
<v-card-title><v-icon icon="mdi-faucet"/>&nbsp;Mock Coin Faucet</v-card-title> <v-card-title><v-icon icon="mdi-faucet"/>&nbsp;Mock Coin Faucet</v-card-title>
<v-card-text>Mockchain provides infinite amounts of MOCK (Mockcoin) and USD (Universally Stable Denomination) for your vault. Click the button below to get a million of each: </v-card-text> <v-card-text>The Dexorder testnet provides infinite amounts of MEH (Mock Ethernet Hardfork) and USXD (Joke Currency XD) for your vault. Click the button below to get a million of each: </v-card-text>
<v-card-item> <v-card-item>
<v-table plain> <v-table plain>
<tbody> <tbody>

View File

@@ -22,7 +22,7 @@ import {connectWallet} from "@/blockchain/wallet.js";
const s = useStore() const s = useStore()
const ok = computed(()=>s.address!==null) const ok = computed(()=>s.account!==null)
</script> </script>

View File

@@ -9,11 +9,12 @@
<th>Filled</th> <th>Filled</th>
<th>Remaining</th> <th>Remaining</th>
<th>Average Price</th> <th>Average Price</th>
<th>Status</th>
<th>&nbsp;</th> <!-- actions --> <th>&nbsp;</th> <!-- actions -->
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr v-for="[index, inTokenAddr, outTokenAddr, amount, amountTokenAddr, filled, avgPrice] in orders"> <tr v-for="[index, inTokenAddr, outTokenAddr, amount, amountTokenAddr, filled, avgPrice, state] in orders">
<td>{{parseInt(index)+1}}</td> <td>{{parseInt(index)+1}}</td>
<td>{{tokenSymbol(inTokenAddr)}}</td> <td>{{tokenSymbol(inTokenAddr)}}</td>
<td>{{tokenSymbol(outTokenAddr)}}</td> <td>{{tokenSymbol(outTokenAddr)}}</td>
@@ -27,6 +28,13 @@
{{pair(inTokenAddr, outTokenAddr, vaultAddr,index)}} {{pair(inTokenAddr, outTokenAddr, vaultAddr,index)}}
</btn> </btn>
</td> </td>
<td>
<v-chip v-if="state===-1" prepend-icon="mdi-signature" color="yellow">Signing</v-chip>
<v-chip v-if="state===0" prepend-icon="mdi-dots-horizontal" color="green">Open</v-chip>
<v-chip v-if="state===1" prepend-icon="mdi-close" color="red">Canceled</v-chip>
<v-chip v-if="state===2" prepend-icon="mdi-check-circle-outline" color="green">Completed</v-chip>
<v-chip v-if="state===3" prepend-icon="mdi-progress-check" color="grey-darken-1">Expired</v-chip>
</td>
</tr> </tr>
</tbody> </tbody>
</v-table> </v-table>
@@ -87,14 +95,26 @@ function pair(inTokenAddr, outTokenAddr, vaultAddr, index) {
const inToken = token(inTokenAddr) const inToken = token(inTokenAddr)
const outToken = token(outTokenAddr) const outToken = token(outTokenAddr)
return !inToken || !outToken ? null : inverted[[vaultAddr,index]] ? return !inToken || !outToken ? null : inverted[[vaultAddr,index]] ?
outToken.symbol+'/'+inToken.symbol : inToken.symbol+'/'+outToken.symbol outToken.symbol+'\\'+inToken.symbol : inToken.symbol+'\\'+outToken.symbol
} }
const orders = computed(()=>{ const orders = computed(()=>{
if( !(vaultAddr.value in s.orders) )
return {}
const result = [] const result = []
for( const [index,status] of Object.entries(s.orders[vaultAddr.value]) ) { console.log('computing orders')
// for( const [status] of pendingOrders.reverse() ) {
// console.log('adding pended order')
// const inTokenAddr = status[0]
// const outTokenAddr = status[1]
// const amountIsInput = !!(status[4])
// const amountTokenAddr = amountIsInput ? inTokenAddr : outTokenAddr
// const amount = 0
// const filled = 0
// const avg = ''
// const state = -1 // pending
// result.push(['...', inTokenAddr, outTokenAddr, amount, amountTokenAddr, filled, avg, state])
// }
if( vaultAddr.value in s.orders ) {
for (const [index, status] of Object.entries(s.orders[vaultAddr.value]).reverse()) {
console.log('order status', status) console.log('order status', status)
// [index, symbolA, symbolB, amount, amountSymbol, filled] // [index, symbolA, symbolB, amount, amountSymbol, filled]
const inTokenAddr = status[0][0] const inTokenAddr = status[0][0]
@@ -112,7 +132,9 @@ const orders = computed(()=>{
const fmtX18 = {decimals: 18, width: 256, signed: false}; const fmtX18 = {decimals: 18, width: 256, signed: false};
const avg = !amountIn || !amountOut ? null : const avg = !amountIn || !amountOut ? null :
FixedNumber.fromValue(status[5], 0, fmtX18).div(FixedNumber.fromValue(status[4], 0, fmtX18)) FixedNumber.fromValue(status[5], 0, fmtX18).div(FixedNumber.fromValue(status[4], 0, fmtX18))
result.push([index, inTokenAddr, outTokenAddr, amount, amountTokenAddr, filled, avg]) const state = status[1]
result.push([index, inTokenAddr, outTokenAddr, amount, amountTokenAddr, filled, avg, state])
}
} }
console.log('result', result) console.log('result', result)
return result return result

View File

@@ -80,7 +80,7 @@
<v-card-actions class="d-flex justify-space-evenly mb-4"> <v-card-actions class="d-flex justify-space-evenly mb-4">
<v-btn variant="outlined" color="red">Cancel</v-btn> <v-btn variant="outlined" color="red">Cancel</v-btn>
<v-btn variant="flat" color="green" :disabled="!validOrder" @click="placeOrder">Place Order</v-btn> <v-btn variant="flat" color="green" :disabled="!validOrder" @click="placeOrder">Place Dexorder</v-btn>
</v-card-actions> </v-card-actions>
</phone-card> </phone-card>
</needs-provider> </needs-provider>
@@ -99,6 +99,7 @@ import {pendOrder} from "@/blockchain/wallet.js";
import NeedsProvider from "@/components/NeedsProvider.vue"; import NeedsProvider from "@/components/NeedsProvider.vue";
import {findRoute} from "@/blockchain/route.js"; import {findRoute} from "@/blockchain/route.js";
import RoutePrice from "@/components/RoutePrice.vue"; import RoutePrice from "@/components/RoutePrice.vue";
import router from "@/router/index.js";
const s = useStore() const s = useStore()
const buy = ref(false) const buy = ref(false)
@@ -127,7 +128,7 @@ const tokenB = computed({
} }
}) })
const pairSymbol = computed(()=>base.value?.symbol+'/'+quote.value?.symbol) const pairSymbol = computed(()=>base.value?.symbol+'\\'+quote.value?.symbol)
const base = computed(()=>{ const base = computed(()=>{
const token = inverted.value ? _tokenB.value : _tokenA.value const token = inverted.value ? _tokenB.value : _tokenA.value
return !token?{}:token return !token?{}:token
@@ -159,10 +160,10 @@ function routeInverted(route) {
const minPrice = ref(null) const minPrice = ref(null)
const maxPrice = ref(null) const maxPrice = ref(null)
const limitPrice = ref(null) const limitPrice = ref(null)
const interval = ref(10) const interval = ref(1)
const intervalIsTotal = ref(true) const intervalIsTotal = ref(true)
const timeUnits = ['minutes', 'hours', 'days'] const timeUnits = ['minutes', 'hours', 'days']
const timeUnitIndex = ref(1) const timeUnitIndex = ref(0)
const limitIsMinimum = computed(() => !(buy.value ^ inverted.value)) const limitIsMinimum = computed(() => !(buy.value ^ inverted.value))
const validOrder = computed(()=>amount.value > 0 && routes.value.length > 0 ) const validOrder = computed(()=>amount.value > 0 && routes.value.length > 0 )
@@ -292,6 +293,7 @@ function placeOrder() {
} }
const order = newOrder(tokenIn, tokenOut, route.exchange, route.fee, amt, amountIsInput, ts) const order = newOrder(tokenIn, tokenOut, route.exchange, route.fee, amt, amountIsInput, ts)
pendOrder(order) pendOrder(order)
router.push('/orders')
} }
</script> </script>

View File

@@ -1,5 +1,4 @@
<template> <template>
<needs-provider>
<!-- todo we can use something like this for ethereum where the vault creation is too expensive to subsidize <!-- todo we can use something like this for ethereum where the vault creation is too expensive to subsidize
<PhoneCard v-if="s.vault===null || s.vault.length === 0"> <PhoneCard v-if="s.vault===null || s.vault.length === 0">
<v-card-title><v-icon color="warning" icon="mdi-safe-square-outline"/>&nbsp;Setup&nbsp;Vault</v-card-title> <v-card-title><v-icon color="warning" icon="mdi-safe-square-outline"/>&nbsp;Setup&nbsp;Vault</v-card-title>
@@ -76,7 +75,6 @@
exists {{ exists }}<br/> exists {{ exists }}<br/>
</div> </div>
--> -->
</needs-provider>
</template> </template>
<script setup> <script setup>

View File

@@ -2,6 +2,7 @@
<needs-provider> <needs-provider>
<needs-signer> <needs-signer>
<orders/> <orders/>
<btn icon="mdi-plus" color="green" class="mt-6" @click="$router.push('/twap')">New Order</btn>
</needs-signer> </needs-signer>
</needs-provider> </needs-provider>
</template> </template>
@@ -10,6 +11,7 @@
import Orders from "@/components/Orders.vue"; import Orders from "@/components/Orders.vue";
import NeedsSigner from "@/components/NeedsSigner.vue"; import NeedsSigner from "@/components/NeedsSigner.vue";
import NeedsProvider from "@/components/NeedsProvider.vue"; import NeedsProvider from "@/components/NeedsProvider.vue";
import Btn from "@/components/Btn.vue";
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">

View File

@@ -11,6 +11,7 @@ import {useStore} from "@/store/store";
import Vault from "@/components/Vault.vue"; import Vault from "@/components/Vault.vue";
import NeedsSigner from "@/components/NeedsSigner.vue"; import NeedsSigner from "@/components/NeedsSigner.vue";
import Faucet from "@/components/Faucet.vue"; import Faucet from "@/components/Faucet.vue";
import NeedsProvider from "@/components/NeedsProvider.vue";
const s = useStore() const s = useStore()