Files
ImmortalClanVue/src/components/TokenClaim.vue
T

375 lines
11 KiB
Vue

<template>
<div class="claim bloodline-border bloodline-border__thin grey">
<div class="claim-headline sub-header">Your Cycle Rewards</div>
<!-- <div class="rewards-wrapper" v-if="!isMobile">
<rewards-wrapper
title="Sacrafice Reward"
coin="$BLOOD"
:amount="getCurrentCycleData?.rewards_sacrifice"
image="/assets/img/vampir.png"
/>
<div class="rewards-divider bloodline-devider">
<font-awesome-icon icon="fa-solid fa-plus" />
</div>
<rewards-wrapper
title="Clan Reward"
coin="$BLOOD"
:amount="getCurrentCycleData?.rewards_clan"
image="/assets/img/vampir.png"
/>
</div> -->
<div class="rewards-list">
<rewards-wrapper
title="Sacrafice Reward"
coin="$BLOOD"
:amount="formatNumber(rewardsSacrifice, 10n ** tokenStore.memeToken.decimals)"
image="/assets/img/vampir.png"
/>
<rewards-wrapper
title="Staking Bonus"
coin="$BLOOD"
:amount="formatNumber(rewardsStaking, 10n ** tokenStore.memeToken.decimals)"
image="/assets/img/vampir.png"
/>
<rewards-wrapper
title="Clan Bonus"
:subTitle="rewardsClan > 0 ? clanBonusPercentage : null"
coin="$BLOOD"
:amount="formatNumber(rewardsClan, 10n ** tokenStore.memeToken.decimals)"
:image="
activeCycle === currentCycle || !cycleStore.getCurrentCycleData?.winner.vamplogo
? '/assets/img/token/notoken.png'
: cycleStore.getCurrentCycleData?.winner.vamplogo
"
/>
</div>
<div class="rewards-total-wrapper">
<div class="rewards-total-headline sub-header">Total Reward</div>
<div
class="rewards-total-inner bloodline-border bloodline-border--variant1"
:class="{ purple: rewardsTotal > 0n && activeCycle !== currentCycle }"
>
<token-name-price
name="$BLOOD"
:price="formatNumber(rewardsTotal, 10n ** tokenStore.memeToken.decimals)"
></token-name-price>
<token-logo img="/assets/img/vampir.png" :size="64" :alt="'vampire'"></token-logo>
</div>
</div>
<div class="claim-button">
<template v-if="!walletStore.connected">
<button class="btn btn-immortal sub-header" @click="showPanel = true">Connect</button>
</template>
<template v-else-if="activeCycle === currentCycle">
<template v-if="rewardsSacrifice > 0n">
<div class="stake-buttons">
<button class="btn btn-immortal sub-header btn--disabled">Claim</button>
<button class="btn btn-immortal sub-header btn--disabled">Stake</button>
</div>
<div>You can claim once the current cycle is finished and the clan bonus calculated</div>
</template>
<template v-else>
<button class="btn btn-immortal sub-header" @click="router.push({ name: 'home' })">
Sacrifice
</button>
</template>
</template>
<template v-else-if="rewardsTotal > 0">
<Transition name="smooth">
<div class="stake-buttons" v-show="!stakeMenu">
<div class="btn btn-immortal sub-header" v-if="stateClaimedComp === 0" @click="claimRewards">
Claim
</div>
<div class="btn btn-immortal sub-header" disabled v-if="stateClaimedComp === 2">
Sign Transaction
</div>
<div class="btn btn-immortal sub-header" disabled v-if="stateClaimedComp === 3">
<loading-component></loading-component>
</div>
<div class="btn btn-immortal sub-header" v-if="stateClaimedComp === 0" @click="openStake">
Stake
</div>
</div>
</Transition>
<Transition name="smooth">
<stake-menu
v-model="tokenNumber"
@close="stakeMenu = false"
:stake="stake"
:amount="rewardsTotal"
v-if="stakeMenu"
>
<template v-slot:body>
<div
class="btn btn-immortal sub-header stake-button"
disabled
v-if="stateStakeClaimComp === 0"
>
Enter Amount
</div>
<div
class="btn btn-immortal sub-header stake-button"
v-else-if="stateStakeClaimComp === 1"
@click="stakeAndClaim"
>
Stake & Claim Rest
</div>
<div
class="btn btn-immortal sub-header stake-button"
disabled
v-if="stateStakeClaimComp === 2"
>
Sign Transaction
</div>
<div
class="btn btn-immortal sub-header stake-button"
disabled
v-if="stateStakeClaimComp === 3"
>
<loading-component></loading-component>
</div>
<div
class="btn transparent small-text cancel-button text-center"
@click="stakeMenu = false"
>
Cancel
</div>
</template>
</stake-menu>
</Transition>
</template>
<template v-else>
<div class="btn btn-immortal btn--disabled sub-header">Nothing to claim</div>
</template>
</div>
</div>
</template>
<script setup>
import { storeToRefs } from "pinia";
import RewardsWrapper from "@/components/RewardsWrapper.vue";
import { inject, ref, onMounted, computed } from "vue";
import { useRewardLockerStore } from "@/stores/rewardlocker";
import { useWalletStoreV2 } from "@/stores/walletV2";
import { useTokenStore } from "@/stores/tokens";
import { useCycleStore } from "@/stores/cycles";
import { useRouter } from "vue-router";
import StakeMenu from "@/components/StakeMenu.vue";
import { waitForTransaction } from "@wagmi/core";
import LoadingComponent from "@/components/LoadingComponent.vue";
import TokenNamePrice from "@/components/TokenNamePrice.vue";
import TokenLogo from "@/components/TokenLogo.vue";
import { formatNumber, formatBigIntDivision } from "@/helper/helper.js";
import { showSuccessToast } from "@/helper/toast.js";
const showPanel = inject("showPanel");
const rewardLockerStore = useRewardLockerStore();
const walletStore = useWalletStoreV2();
const tokenStore = useTokenStore();
const cycleStore = useCycleStore();
const router = useRouter();
const { activeCycle, currentCycle, getCurrentCycleData, rewardsSacrifice, rewardsStaking, rewardsClan, rewardsTotal } =
storeToRefs(cycleStore);
const stakeMenu = ref(false);
const stake = ref(null);
const tokenNumber = ref(null);
const stateClaim = ref(0);
const stateStakeClaim = ref(0);
async function stakeAndClaim() {
try {
console.log("stakeAndClaim");
console.log(tokenNumber.value);
console.log(rewardsTotal.value);
stateStakeClaim.value = 2;
console.log("hier1");
const coefficient = (10000n * BigInt(tokenNumber.value)) / rewardsTotal.value;
var hash = await rewardLockerStore.stakeAndClaimCycle(coefficient, cycleStore.activeCycle);
console.log("hier2");
stateStakeClaim.value = 3;
console.log("hash");
const data = await waitForTransaction({
hash: hash,
});
console.log("data", data);
stateStakeClaim.value = 4;
//ClaimedReward (address staker, uint256 reward)
var rewardData = data.logs.find((logObject) => {
return logObject.topics.find(
(topic) => topic === "0xd0813ff03c470dcc7baa9ce36914dc2febdfd276d639deffaac383fd3db42ba3"
);
});
var stakeData = data.logs.find((logObject) => {
return logObject.topics.find(
(topic) => topic === "0xf496bf2b14b1d178412b6f7a745900105b49b38b315cfdfbfabad31a6f995c6f"
);
});
//
console.log("rewardData", rewardData);
console.log("stakeData", stakeData);
const outputClaim = BigInt(rewardData?.topics[2]);
const outputStaked = BigInt(stakeData?.topics[3]);
showSuccessToast(
formatNumber(outputClaim + outputStaked, 10n ** tokenStore.memeToken.decimals),
"Success!",
"You just claimed and staked",
"Join the next cycle to increase your rewards and win with your clan."
);
tokenNumber.value = 0;
stakeMenu.value = false;
await walletStore.loadWalletData();
} catch (error) {
console.error("stakeAndClaim", error);
} finally {
const walletStore = useWalletStoreV2();
await walletStore.loadWalletData();
console.log("finally1");
await cycleStore.fillCycle(activeCycle.value, true);
console.log("finally2");
stateStakeClaim.value = 1;
}
}
function openStake() {
stake.value = true;
stakeMenu.value = true;
}
onMounted(async () => {});
async function claimRewards() {
try {
stateClaim.value = 2;
console.log("getCurrentCycleData", getCurrentCycleData);
console.log("activeCycle.value", activeCycle.value);
var hash = await rewardLockerStore.claim([activeCycle.value]);
stateClaim.value = 3;
console.log("hash", hash);
const data = await waitForTransaction({
hash: hash,
});
stateClaim.value = 4;
// ClaimedReward (address staker, uint256 reward)
var rewardData = data.logs.find((logObject) => {
return logObject.topics.find(
(topic) => topic === "0xd0813ff03c470dcc7baa9ce36914dc2febdfd276d639deffaac383fd3db42ba3"
);
});
//
console.log("rewardData", rewardData);
const outputClaim = formatNumber(BigInt(rewardData.topics[2]), 10n ** tokenStore.memeToken.decimals);
showSuccessToast(
outputClaim,
"Success!",
"You just claimed",
"Join the next cycle to increase your rewards and win with your clan."
);
await cycleStore.fillCycle(activeCycle.value, true);
await walletStore.loadWalletData();
} catch (error) {
stateClaim.value = 0;
throw Error(error);
}
}
const clanBonusPercentage = computed(() => {
return (
(
(formatBigIntDivision(rewardsClan.value, 10n ** tokenStore.memeToken.decimals, 8) /
formatBigIntDivision(rewardsTotal.value, 10n ** tokenStore.memeToken.decimals, 8)) *
100
).toFixed(2) + "%"
);
});
const stateClaimedComp = computed(() => {
let returnState = 0;
if (stateClaim.value === 2) {
returnState = 2;
} else if (stateClaim.value === 3) {
returnState = 3;
}
return returnState;
});
const stateStakeClaimComp = computed(() => {
console.log("stateStakeClaimComp");
let returnState = 0;
if (stateStakeClaim.value === 2) {
returnState = 2;
} else if (stateStakeClaim.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 ||
BigInt(tokenNumber.value) > walletStore.unclaimedRewards / 10n ** tokenStore.memeToken.decimals
) {
returnState = 0;
}
return returnState;
});
</script>
<style lang="sass">
.claim
display: flex
padding: 12px
flex-direction: column
gap: 16px
@media (min-width: 992px)
padding: 32px 40px
.claim-headline
text-align: left
.claim-button
text-align: center
display: flex
flex-direction: column
gap: 24px
.stake-buttons
display: flex
text-align: center
gap: 8px
@media (min-width: 992px)
gap: 32px
// div
// flex: 1 1 50%
margin-bottom: 16px
.rewards-divider
text-align: center
.rewards-total-wrapper
display: flex
flex-direction: column
gap: 8px
.rewards-total-headline
text-align: left
.rewards-total-inner
display: flex
justify-content: space-between
text-align: left
box-sizing: content-box
.rewards-left
display: flex
flex-direction: column
gap: 8px
.name
font-size: 16px
.amount
font-size: 24px
.rewards-right
img
height: 49px
width: 49px
border-radius: 50%
</style>