Files
web/src/components/Vault.vue
2025-04-26 14:56:55 -04:00

148 lines
4.9 KiB
Vue

<template>
<div>
<div v-if="!hasVault">
<v-card-title>
Creating Your Dexorder Vault
<v-icon icon="mdi-safe-square" size="small" color="grey-darken-1" style="vertical-align: baseline"/>
</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">
Please wait while your vault is being created. This should only take a few seconds...
</v-card-text>
</div>
<div v-if="hasVault">
<v-card-subtitle class="overflow-x-hidden">
<copy-button :text="addr">Deposit {{addr}}</copy-button>
</v-card-subtitle>
<v-card-text v-if="empty">
<!--
<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 asking your vault to execute 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 trading vault.
</p>
<p v-if="s.mockenv">
There are no funds currently in your vault. Use the faucet below to mint some testnet coins.
</p>
</v-card-text>
<v-card-item v-if="!empty">
<v-table>
<tbody>
<native-row v-if="nativeBalance" :chain-id="s.chainId" :addr="s.vault" :amount="nativeBalance"
:on-withdraw="onWithdrawNative" :on-wrap="()=>wrapShow=true"/>
<suspense v-for="(amount,addr) of balances">
<token-row v-if="BigInt(amount)>0n" :chain-id="s.chainId" :addr="addr" :amount="amount" :onWithdraw="onWithdraw"/>
</suspense>
</tbody>
</v-table>
</v-card-item>
</div>
<withdraw :vault="addr" :token="withdrawToken" v-model="withdrawShow"/>
<withdraw-native :vault="addr" v-model="withdrawNativeShow" :balance="nativeBalance"/>
<native-wrap :vault="addr" v-model="wrapShow" :max-amount="nativeBalance"/>
</div>
<!--
<div>
addr {{ addr }}<br/>
empty {{ empty }}<br/>
exists {{ exists }}<br/>
</div>
-->
</template>
<script setup>
import {useStore} from "@/store/store.js";
import {computed, defineAsyncComponent, onUnmounted, ref, watchEffect} from "vue";
import {vaultAddress} from "@/blockchain/contract.js";
import {ensureVault} from "@/blockchain/wallet.js";
import CopyButton from "@/components/CopyButton.vue";
import Withdraw from "@/components/Withdraw.vue";
import NativeRow from "@/components/NativeRow.vue";
import NativeWrap from "@/components/NativeWrap.vue";
import WithdrawNative from "@/components/WithdrawNative.vue";
import {provider} from "@/blockchain/provider.js";
const TokenRow = defineAsyncComponent(()=>import('./TokenRow.vue'))
const s = useStore()
const props = defineProps(['owner', 'num'])
const addr = computed(()=>vaultAddress(s.factory, s.vaultInitCodeHash, props.owner, props.num))
const balances = computed(()=>{
const bs = s.vaultBalances[addr.value]
console.log('balances', addr.value, s.vaultBalances, bs)
return bs || {}
})
const empty = computed(()=>{
if(nativeBalance.value!==0n) return false
for( const v of Object.values(balances.value) )
if(BigInt(v)!==0n)
return false
return true
})
const hasVault = computed(()=>s.vault!==null)
const withdrawToken = ref(null)
const withdrawShow = ref(false)
async function onWithdraw(token) {
console.log('withdraw', addr, token)
withdrawToken.value = token
withdrawShow.value = true
}
const withdrawNativeShow = ref(false)
async function onWithdrawNative() {
withdrawNativeShow.value = true
}
const wrapShow = ref(false)
const nativeBalance = ref(null)
async function updateNativeBalance() {
// unfortunately there is no better way than polling, unless we start tracking in the backend. i assume the wallets
// cache this data anyway and are not actually polling their backends
if (provider) {
const s = useStore();
const vault = s.vault;
if (vault) {
const balance = await provider.getBalance(vault)
console.log('native balance', vault, balance)
if (s.vault===vault) // could have changed during async
nativeBalance.value = balance
else
console.warn('vault changed during balance update', vault, s.vault)
}
}
}
updateNativeBalance()
const timeout = setInterval(updateNativeBalance, 5000)
onUnmounted(()=>clearInterval(timeout))
function checkVault() {
console.log('checkVault', props.num, s.account, s.vault)
if(props.num===0 && s.account && !s.vault)
ensureVault()
}
watchEffect(checkVault)
checkVault()
</script>
<style scoped lang="scss">
@use "../styles/vars" as *;
p {
margin-top: 1.5em;
}
</style>