Files
ImmortalClanVue/src/components/StakeComponentV1.vue
T

330 lines
9.1 KiB
Vue

<template>
<div
:class="{
'stake-component--variant1': props.variant === 1,
'stake-component--variant2': props.variant === 2,
'stake-component--variant3': props.variant === 3,
}"
>
<div class="mid-text text-center" v-if="props.variant === 2">
<slot name="headline">Staked</slot>
</div>
<div
class="connected-stake bloodline-border card"
:class="{ 'card--dense': dense, 'connected-stake--variant1': variant === 1 }"
@click="
(e) => {
e.preventDefault();
e.stopPropagation();
}
"
>
<div class="connected-stake-headline mid-mid-text">
<slot name="headline" v-if="variant !== 2">Staked</slot>
</div>
<div class="connected-stake-subheadline low-mid-text">
<slot name="subheadline"
>Stake for a 25% bonus on your sacrifice.<br />
Upper limit is your stake.</slot
>
</div>
<div class="connected-stake-body">
<slot name="body">
<token-name-price
:name="tokenStore.getToken(walletStore.memeToken?.contractAddress)?.name"
:price="formatNumber(walletStore.memeToken?.staked)"
></token-name-price>
<token-logo img="/assets/img/token/bloodline.png" :alt="'bloodline-token'"></token-logo>
<token-name-price class="stake-reward" name="Extra Reward" price="+25%"></token-name-price>
</slot>
</div>
<slot name="actions">
<div class="connected-stake-buttons" v-if="!stakeMenu">
<div class="mid-mid-text text-center" disabled v-if="!walletStore.connected">
Please Connect Your Wallet
</div>
<div
class="btn btn-immortal mid-mid-text"
disabled
v-if="walletStore.connected && cycleStore.currentCycle === 1"
>
Stake
</div>
<div
class="btn btn-immortal mid-mid-text"
v-else-if="walletStore.connected && cycleStore.currentCycle > 1"
@click="openStake"
>
Stake
</div>
<div
v-if="
walletStore.connected &&
((walletStore.memeToken?.staked === 0 && !stakeonly) || cycleStore.currentCycle === 1)
"
class="btn btn-immortal btn--disabled mid-mid-text"
>
Unstake
</div>
<div
v-else-if="walletStore.connected && !stakeonly"
class="btn btn-immortal mid-mid-text"
@click="openUnstake"
>
Unstake
</div>
</div>
<Transition name="smooth">
<stake-menu
v-model="tokenNumber"
@close="stakeMenu = false"
:stake="stake"
:amount="walletStore.memeToken?.balanceOf"
v-if="stakeMenu & !unstakeMenu"
>
<template v-slot:body>
<div class="btn btn-immortal stake-button" disabled v-if="stateStake === 0">
Enter Amount
</div>
<div class="btn btn-immortal stake-button" v-else-if="stateStake === 1" @click="stakeToken">
Stake
</div>
<div class="btn btn-immortal stake-button" disabled v-if="stateStake === 2">
Sign Transaction
</div>
<div class="btn btn-immortal stake-button" disabled v-if="stateStake === 3">
<loading-component></loading-component>
</div>
<div
class="btn transparent small-text cancel-button text-center"
@click="stakeMenu = false"
>
Cancel
</div>
</template>
<template v-slot:message-end>
<div class="input-balance">Balance: {{ walletStore.memeToken?.balanceOf }}</div>
</template>
</stake-menu>
<div class="unstake-menu" v-else-if="stakeMenu & unstakeMenu">
<div class="low-mid-text text-center">
To prevent users from farming rewards you can claim your stake next cycle.
</div>
<div class="unstake-menu-actions">
<div class="btn btn-immortal stake-button" v-if="stateStake <= 1" @click="orderUnstake">
Unstake Next Cycle
</div>
<div class="btn btn--disabled mid-mid-text text-center" v-else-if="stateStake === 2">
Sign Transaction
</div>
<div class="btn btn--disabled mid-mid-text text-center" v-else-if="stateStake === 3">
<loading-component></loading-component>
</div>
<div
class="btn transparent small-text cancel-button text-center"
@click="stakeMenu = false"
>
Cancel
</div>
</div>
</div>
</Transition>
<div class="connected-stake-first-round small-text text-center" v-if="cycleStore.currentCycle === 0">
No $BLOOD on the market. Staking is activated after the first cycle is finished.
</div>
</slot>
<slot></slot>
</div>
</div>
</template>
<script setup>
import { ref, useSlots, computed } from "vue";
import StakeMenu from "@/components/StakeMenu.vue";
import TokenNamePrice from "@/components/TokenNamePrice.vue";
import TokenLogo from "@/components/TokenLogo.vue";
import { waitForTransaction } from "@wagmi/core";
import LoadingComponent from "@/components/LoadingComponent.vue";
import { showSuccessToast } from "@/helper/toast.js";
import { useCycleStore } from "@/stores/cycles";
import { useRewardLockerStore } from "@/stores/rewardlocker";
import { useWalletStoreV2 } from "@/stores/walletV2";
import { useTokenStore } from "@/stores/tokens";
import { useToast } from "vue-toastification";
import { formatNumber } from "@/helper/helper.js";
const toast = useToast();
const walletStore = useWalletStoreV2();
const tokenStore = useTokenStore();
const rewardLockerStore = useRewardLockerStore();
const cycleStore = useCycleStore();
const slots = useSlots();
const props = defineProps({
stakeonly: {
type: Boolean,
required: false,
default: false,
},
variant: {
type: Number,
required: false,
default: null,
},
dense: {
type: Boolean,
required: false,
default: false,
},
});
const stakeMenu = ref(false);
const unstakeMenu = ref(false);
const stake = ref(null);
const tokenNumber = ref(null);
const loading = ref(false);
/**
* state 0 enter amount
* state 1 rdy to go
* state 2 signing
* state 3 loading
* state 4 staked
*/
const state = ref(0);
function openStake() {
stake.value = true;
unstakeMenu.value = false;
stakeMenu.value = true;
}
function openUnstake() {
stake.value = false;
unstakeMenu.value = true;
stakeMenu.value = true;
}
async function orderUnstake() {
try {
state.value = 2;
var hash = await rewardLockerStore.orderUnstake();
state.value = 3;
const data = await waitForTransaction({
hash: hash,
});
state.value = 4;
var rewardData = data.logs.find((logObject) => {
return logObject.topics.find(
(topic) => topic === "0xd0813ff03c470dcc7baa9ce36914dc2febdfd276d639deffaac383fd3db42ba3"
);
});
console.log("rewardData", rewardData);
const outputClaim = Number(rewardData.topics[2]) / Math.pow(10, tokenStore.memeToken.decimals);
showSuccessToast(
formatNumber(outputClaim),
"Success!",
"You just unstaked",
"You can claim your stake next cycle."
);
await walletStore.loadWalletData();
} catch (error) {
console.error("orderUnstake", error);
} finally {
state.value = 0;
}
}
async function stakeToken() {
try {
state.value = 2;
const hash = await rewardLockerStore.stakeBloodline(tokenNumber.value);
state.value = 3;
const data = await waitForTransaction({
hash: hash,
});
var rewardData = data.logs.find((logObject) => {
return logObject.topics.find(
(topic) => topic === "0xf496bf2b14b1d178412b6f7a745900105b49b38b315cfdfbfabad31a6f995c6f"
);
});
//
console.log("rewardData", rewardData);
const outputClaim = Number(rewardData.topics[3]) / Math.pow(10, tokenStore.memeToken.decimals);
console.log("data", data);
state.value = 4;
await walletStore.loadWalletData();
showSuccessToast(
formatNumber(outputClaim),
"Success!",
"You just staked",
"Your next sacrifice will get an extra staking bonus as a reward."
);
//reload data
} catch (error) {
console.error(error);
throw new Error(error);
} finally {
state.value = 0;
}
}
const stateStake = computed(() => {
let returnState = 0;
if (state.value === 2) {
returnState = 2;
} else if (state.value === 3) {
returnState = 3;
} else if (tokenNumber.value !== null || tokenNumber.value !== "" || tokenNumber.value > 0) {
returnState = 1;
} else if (tokenNumber.value === null || tokenNumber.value === "" || tokenNumber.value === 0) {
returnState = 0;
}
return returnState;
});
</script>
<style lang="sass">
.stake-component--variant2
border-radius: 16px
background: var(--darkgrey, #202020)
display: flex
flex-direction: column
gap: 18px
padding: 8px
@media (min-width: 992px)
padding: 24px 48px
.unstake-menu
display: flex
flex-direction: column
gap: 16px
.unstake-menu-actions
display: flex
flex-direction: column
gap: 8px
.stake-component--variant3
.connected-stake
.connected-stake-headline
text-align: left
.connected-stake-body
.token-price-wrapper, .stake-reward
.token-name
font-size: 14px
.token-price
font-size: 24px
.connected-stake-buttons
display: flex
gap: 8px
.btn
font-size: 18px
.connected-stake-first-round
font-size: 14px
.connected-stake-claim-info
font-size: 14px
</style>