Skip to content

Commit

Permalink
general improvements, global config and reward pool deposit/withdraw
Browse files Browse the repository at this point in the history
  • Loading branch information
marc0olo committed Aug 2, 2023
1 parent cc9bafd commit b4b0d66
Show file tree
Hide file tree
Showing 9 changed files with 243 additions and 20 deletions.
2 changes: 1 addition & 1 deletion development/smart-contracts/scripts/claimAndWrapName.js
@@ -1,5 +1,5 @@
require('dotenv').config({ path: '.env.local' });
const { AeSdk, CompilerHttp, MemoryAccount, Node } = require('@aeternity/aepp-sdk');
const { AeSdk, MemoryAccount, Node } = require('@aeternity/aepp-sdk');

// https://github.com/GoogleChromeLabs/jsbi/issues/30#issuecomment-953187833
BigInt.prototype.toJSON = function() { return this.toString() }
Expand Down
2 changes: 1 addition & 1 deletion development/smart-contracts/scripts/deploy.js
@@ -1,6 +1,6 @@
require('dotenv').config({ path: '.env.local' });
const fs = require('fs');
const { AeSdk, CompilerHttp, MemoryAccount, Node } = require('@aeternity/aepp-sdk');
const { AeSdk, MemoryAccount, Node } = require('@aeternity/aepp-sdk');

const shutdown = (varName) => {
console.error(`Missing ENV variable: ${varName}`);
Expand Down
3 changes: 2 additions & 1 deletion development/ui/.env.development
Expand Up @@ -2,4 +2,5 @@ VUE_APP_NETWORK_ID=ae_uat
VUE_APP_NETWORK_NAME=testnet
VUE_APP_NODE_URL=https://testnet.aeternity.io
VUE_APP_AESCAN_URL=https://testnet.aescan.io
VUE_APP_CONTRACT_ID=ct_2Jc4iTsMWouenbuPQLZT4f8bPLHH4PJuPvVRQMZ1LECyhCzucB
#VUE_APP_CONTRACT_ID=ct_2Jc4iTsMWouenbuPQLZT4f8bPLHH4PJuPvVRQMZ1LECyhCzucB
VUE_APP_CONTRACT_ID=ct_CC9KdmMx9kFTVCguwP4oUfEfydB7PaHnhr2df4tm9EmWa6oH2
1 change: 1 addition & 0 deletions development/ui/.eslintrc.js
Expand Up @@ -2,6 +2,7 @@ module.exports = {
root: true,
env: {
node: true,
es2020: true
},
extends: ['plugin:vue/vue3-essential', 'eslint:recommended'],
parserOptions: {
Expand Down
3 changes: 2 additions & 1 deletion development/ui/src/App.vue
Expand Up @@ -6,7 +6,8 @@
<router-link to="/">Home</router-link> |
<router-link to="/contract-interaction">Contract Interaction</router-link> |
<router-link to="/wrap-names">Wrap AENS names</router-link> |
<router-link to="/my-nfts">My NFTs</router-link>
<router-link to="/my-nfts">My NFTs</router-link> |
<router-link to="/my-config">My Config</router-link>
</div>
</div>

Expand Down
10 changes: 9 additions & 1 deletion development/ui/src/router/index.js
Expand Up @@ -38,7 +38,15 @@ const routes = [
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/NftDetails.vue')
}
},
{
path: '/my-config',
name: 'MyConfig',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/MyConfig.vue')
},
]

const router = createRouter({
Expand Down
209 changes: 209 additions & 0 deletions development/ui/src/views/MyConfig.vue
@@ -0,0 +1,209 @@
<template>
<div>
<h2>Reward Pool</h2>
<p v-if="isWaiting">Waiting for wallet connection ...</p>
<div v-else>
Currently: {{ toAe(rewardPool) }} AE
<br /><br />
<button @click="withdraw(true)">
withdraw all
</button>
<br /><br />
<div>
<span>
<strong>Amount to add/withdraw: </strong>
<input v-model="amount" />
</span>
<button @click="deposit()">
deposit
</button>
<button @click="withdraw(false)">
withdraw
</button>
</div>
</div>
<h2>Config</h2>
<p v-if="isWaiting">Waiting for wallet connection ...</p>
<div v-if="globalConfig">
<div class="my-config-container">
<ul>
<li>Reward: {{ toAe(globalConfig.reward) }} AE</li>
<li>Reward Block Window: {{ globalConfig.reward_block_window }}</li>
<li>Emergency Reward: {{ toAe(globalConfig.emergency_reward) }} AE</li>
<li>Emergency Reward Block Window: {{ globalConfig.emergency_reward_block_window }}</li>
<li>NFTs can receive AENS names from others: {{ globalConfig.can_receive_from_others }}</li>
<li>NFTs burnable if expired or empty: {{ globalConfig.burnable_if_expired_or_empty }}</li>
</ul>
</div>
<br /><br />
</div>
<div v-else-if="!isWaiting">
You haven't set a config yet. <br /><br />
</div>
<div v-if="!isWaiting">
<span>
<strong>Reward (AE): </strong>
<input v-model="reward" />
</span>
<br />
<span>
<strong>Reward Block Window: </strong>
<input v-model="rewardBlockWindow" />
</span>
<br />
<span>
<strong>Emergency Reward (AE): </strong>
<input v-model="emergencyReward" />
</span>
<br />
<span>
<strong>Emergency Reward Block Window: </strong>
<input v-model="emergencyRewardBlockWindow" />
</span>
<br />
<span>
<strong>NFTs can receive AENS names: </strong>
<input v-model="canReceive" type="checkbox"/>
</span>
<br />
<span>
<strong>NFTs burnable if expired or empty: </strong>
<input v-model="burnable" type="checkbox" />
</span>
<br /><br />
<button @click="setConfig()">
set/update config
</button>
</div>
<p v-if="txExecuting">Waiting for tx to be mined ...</p>
<p v-if="txHash">
Transaction mined:
<a :href="`${state.aeScanUrl}/transactions/${txHash}`"
target="_blank"
rel="noreferrer">
{{ txHash }}
</a>
</p>
</div>
</template>

<script setup>
import { toAe, toAettos } from '@aeternity/aepp-sdk'
import { ref } from 'vue'
import { state } from '../utils/aeternity/aeternity'
let globalConfig = ref()
let rewardPool = ref()
let amount = ref()
let reward = ref(0)
let rewardBlockWindow = ref(0)
let emergencyReward = ref(0)
let emergencyRewardBlockWindow = ref(0)
let canReceive = ref(false)
let burnable = ref(false)
let isWaiting = ref(true)
let txExecuting = ref(false)
let txHash = ref()
const loadData = async () => {
while(isWaiting.value) {
if(state.status === 'connected') {
globalConfig.value = (await state.contract.get_global_config(state.aeSdk.address)).decodedResult
rewardPool.value = (await state.contract.get_reward_pool(state.aeSdk.address)).decodedResult
isWaiting.value = false
}
await delay(1000)
}
}
const deposit = async () => {
if(!amount.value || amount.value <= 0 || isNaN(amount.value)) {
alert("amount must be a number > 0")
return
}
txExecuting.value = true
try {
const tx = await state.contract.deposit_to_reward_pool({ amount: toAettos(amount.value) })
txHash.value = tx.hash
console.log(tx)
} catch(e) {
alert(e)
}
txExecuting.value = false
}
const withdraw = async (all) => {
let aettos
if(all) {
if(rewardPool.value == 0) {
alert("nothing to withdraw")
return
}
} else {
if(!amount.value || amount.value <= 0 || isNaN(amount.value)) {
alert("amount must be a number > 0")
return
}
aettos = toAettos(amount.value)
if(aettos > rewardPool.value) {
alert("can't withdraw more AE than in pool")
return
}
}
txExecuting.value = true
try {
const tx = all
? await state.contract.withdraw_from_reward_pool()
: await state.contract.withdraw_from_reward_pool(aettos)
txHash.value = tx.hash
console.log(tx)
} catch(e) {
alert(e)
}
txExecuting.value = false
}
const setConfig = async () => {
txExecuting.value = true
try {
const config = {
reward: toAettos(reward.value),
reward_block_window: rewardBlockWindow.value,
emergency_reward: toAettos(emergencyReward.value),
emergency_reward_block_window: emergencyRewardBlockWindow.value,
can_receive_from_others: canReceive.value,
burnable_if_expired_or_empty: burnable.value
}
const tx = await state.contract.set_global_config(config)
txHash.value = tx.hash
console.log(tx)
} catch(e) {
alert(e)
}
txExecuting.value = false
}
const delay = (millisec) => {
return new Promise(resolve => {
setTimeout(() => { resolve() }, millisec);
})
}
loadData()
</script>

<style scoped>
.my-config-container {
margin: 0 auto;
max-width: 720px;
display: flex;
justify-content: center;
border: 2px solid #de3f6b;
border-radius: 15px;
padding: 10px;
}
</style>
3 changes: 0 additions & 3 deletions development/ui/src/views/MyNfts.vue
Expand Up @@ -21,9 +21,6 @@
<div v-else-if="!isWaiting">
You don't own an NFT.
</div>
<div>
<NftDetails />
</div>
<p v-if="txExecuting">Waiting for tx to be mined ...</p>
<p v-if="txHash">
Transaction mined:
Expand Down
30 changes: 18 additions & 12 deletions development/ui/src/views/NftDetails.vue
Expand Up @@ -8,24 +8,27 @@
<ul>
<li>Owner: {{ nftData.owner }}</li>
<li>Expiration height: {{ nftData.expiration_height }}</li>
<ul>
<li>{{ nftData.expiration_height - BigInt(currentHeight) }} keyblocks left</li>
</ul>
<li v-if="nftData.names.length > 0">Names:</li>
<ul v-if="nftData.names.length > 0">
<li v-for="name in nftData?.names" :key="name">
{{ name }}
</li>
</ul>
<li v-else>Names: n/a</li>
<li v-if="nftData.config">Config:</li>
<ul v-if="nftData.config">
<li>Reward: {{ nftData.config.reward }}</li>
<li>Reward block window: {{ nftData.config.reward_block_window }}</li>
<li>Emergency reward: {{ nftData.config.emergency_reward }}</li>
<li>Emergency reward block window: {{ nftData.config.emergency_reward_block_window }}</li>
<li>Can receive from others: {{ nftData.config.can_receive_from_others }}</li>
<li>Burnable if expired or empty: {{ nftData.config.burnable_if_expired_or_empty }}</li>
<li v-if="nftData.owner_config">Config:</li>
<ul v-if="nftData.owner_config">
<li>Reward: {{ toAe(nftData.owner_config.reward) }} AE</li>
<li>Reward block window: {{ nftData.owner_config.reward_block_window }}</li>
<li>Emergency reward: {{ toAe(nftData.owner_config.emergency_reward) }} AE</li>
<li>Emergency reward block window: {{ nftData.owner_config.emergency_reward_block_window }}</li>
<li>Can receive from others: {{ nftData.owner_config.can_receive_from_others }}</li>
<li>Burnable if expired or empty: {{ nftData.owner_config.burnable_if_expired_or_empty }}</li>
</ul>
<li v-else>Config: n/a</li>
<li>Estimated reward: {{ estimatedReward }}</li>
<li>Current reward for extending: {{ toAe(estimatedReward) }} AE</li>
</ul>
</div>
</div>
Expand All @@ -42,7 +45,7 @@
</div>
<div>
<span>
<strong>Name(s) to unwrap (comma separated): </strong>
<strong>Name(s) to unwrap (comma separated): </strong>
<input v-model="namesToUnwrap" placeholder="xyz.chain" />
</span>
<button @click="unwrapSingle()">
Expand Down Expand Up @@ -85,24 +88,27 @@
import { ref } from 'vue';
import { useRoute } from 'vue-router'
import { state } from '../utils/aeternity/aeternity'
import { toAe } from '@aeternity/aepp-sdk';
const route = useRoute();
const nftId = route.params.id; // read parameter id (it is reactive)
let isLoading = ref(true)
let nftData = ref()
let currentHeight = ref()
let estimatedReward = ref()
let recipient = ref()
let namesToUnwrap = ref()
let txExecuting = ref(false)
let txHash = ref()
const loadNftData = async () => {
const loadData = async () => {
while(isLoading.value) {
if(state.status === 'connected') {
try {
nftData.value = (await state.contract.get_nft_data(nftId)).decodedResult
estimatedReward.value = (await state.contract.estimate_reward(nftId)).decodedResult
currentHeight.value = await state.aeSdk.getHeight()
} catch (e) {
console.error(e)
}
Expand Down Expand Up @@ -213,7 +219,7 @@
})
}
loadNftData()
loadData()
</script>
<style scoped>
Expand Down

0 comments on commit b4b0d66

Please sign in to comment.