I am trying to build this pretty simple fetching function:
const fetchUnstakedNFTs = async (): Promise<void> => {
if (wallet.value && wallet.value.connected && publicKey.value) {
const tokenAccountsFromWallet =
await connection.getParsedTokenAccountsByOwner(publicKey.value, {
programId: new PublicKey(
"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
),
});
// Define and/or reset tokenAccounts Array
const tokenAccounts: {
pubkey: PublicKey;
account: AccountInfo<ParsedAccountData>;
}[] = [];
for (const account of tokenAccountsFromWallet.value) {
const metadata = await getMetadata(
account.account.data.parsed.info.mint
);
// Add NFTs with matching creator and amount === 1 to tokenAccounts
if (
metadata &&
metadata.creators &&
metadata.creators[0].address === nftCreator.toString() &&
account.account.data.parsed.info.tokenAmount.amount === "1"
) {
tokenAccounts.push(account);
}
}
// Add tokenAccounts to unstakedNFTs if they are not already in there
for (const tokenAccount of tokenAccounts) {
const metadata = await getMetadata(
tokenAccount.account.data.parsed.info.mint
);
if (
metadata &&
metadata.creators &&
metadata.creators[0].address == nftCreator.toString()
) {
const { data } = await axios.get(metadata.uri);
const newNFT = {
name: data.name,
symbol: metadata.symbol,
image: data.image,
mintId: tokenAccount.account.data.parsed.info.mint,
tokenAccount: tokenAccount.pubkey.toString(),
isStaking: false,
isSelected: false,
};
// check if unstakedNFTs contains the NFT already
if (
!unstakedNFTs.value.find(
(nft) =>
nft.mintId === newNFT.mintId &&
nft.tokenAccount === newNFT.tokenAccount
)
) {
// if it doesnt, add it to unstakedNFTs
console.log("Adding NFT to unstakedNFTs", newNFT);
unstakedNFTs.value.push(newNFT);
}
}
}
}
};
But I am getting this warning:
Maximum recursive updates exceeded in component . This means you have a reactive effect that is mutating its own dependencies and thus recursively triggering itself. Possible sources include component template, render function, updated hook or watcher source function.
instrumentations.<computed> @ reactivity.esm-bundler.js?89dc:439
fetchUnstakedNFTs @ createWalletStore.ts?a4c6:344
I have no Idea what to try anymore.
Looking at this part of the warning:
fetchUnstakedNFTs @ createWalletStore.ts?a4c6:344
You can see that it points to this line of my function (line 344):
unstakedNFTs.value.push(newNFT);
Here the NFTPane.vue
Component:
<template>
<div >
<div v-if="wallet.fetching && nfts.length == 0">
<div v-for="item in shimmerArray" :key="item" >
</div>
</div>
<div v-else >
<button :disabled="nft.isStaking" @click="selectNFT(nft)" v-for="nft in nfts" :key="nft.image"
>
<img
:
:src="nft.image" />
<div
>
#{{ getNFTNumber(nft.name) }}
</div>
</button>
</div>
<div >
<button @click="onStake()">
<span>
{{ stakeType == StakeType.unstaked ? 'Stake' : 'Unstake' }}
</span>
</button>
<button @click="onStakeAll()">
<span>
{{ stakeType == StakeType.unstaked ? 'Stake All' : 'Unstake All' }}
</span>
</button>
<button v-if="stakeType == StakeType.staked" @click="claimAllRewards()" >
<span>
Claim Rewards
</span>
</button>
</div>
</div>
</template>
<script lang="ts" setup>
import { defineProps, ref } from 'vue';
import { PublicKey } from '@solana/web3.js';
import { NFT, StakeType } from '@/types/types';
import { useWallet, useAnchorWallet } from '@/composables/useWallet/index';
import { claimNFTRewards } from '@/plugins/utils/claim_rewards/src/claim_rewards'
import { connection, stakePoolID } from '@/constants';
import { createToast } from '@/plugins/toast/createToast';
import { unstakeNFT } from '@/plugins/utils/unstake/src/unstake';
import { stakeNFT } from '@/plugins/utils/stake/src/stake';
import { getNFTNumber } from '@/composables/utils';
// import FadeLoader from 'vue-spinner/src/FadeLoader.vue';
const props = defineProps<{
nfts: NFT[],
stakeType: StakeType,
}>();
const wallet = useWallet();
const anchorWallet = useAnchorWallet();
const shimmerArray = Array(9)
const selectNFT = async (nft: NFT) => {
nft.isSelected = !nft.isSelected;
}
const claimAllRewards = async () => {
if (anchorWallet.value) {
claimNFTRewards(
connection,
anchorWallet.value,
{
stakePoolId: stakePoolID,
nfts: wallet.stakedNFTs.value,
callback: () => {
createToast('Successfully claimed rewards', {
type: 'success',
});
}
}
);
}
};
const onStakeAll = async () => {
if (props.stakeType == StakeType.staked) {
wallet.stakedNFTs.value = wallet.stakedNFTs.value.map(stakedNFT => {
stakedNFT.isSelected = true;
return stakedNFT;
});
}
else {
wallet.unstakedNFTs.value = wallet.unstakedNFTs.value.map(unstakedNFT => {
unstakedNFT.isSelected = true;
return unstakedNFT;
});
}
await onStake();
}
const onStake = async () => {
const alertIndex = ref(0);
if (anchorWallet.value) {
if (StakeType.staked == props.stakeType) {
const nfts = wallet.stakedNFTs.value.filter(stakedNFT => stakedNFT.isSelected);
nfts.forEach((nft) => nft.isStaking = true)
wallet.staking.value = true;
try {
await unstakeNFT(connection, anchorWallet.value, {
stakePoolId: stakePoolID,
originalMintId: nfts.map(nft => new PublicKey(nft.mintId)),
callback: () => {
alertIndex.value ;
if (nfts.length === 1) {
createToast("Successfully Unstaked NFT", {
type: "success",
transition: "zoom",
timeout: 5000,
showIcon: true,
});
}
else {
createToast(`${alertIndex.value}/${nfts.length} Successfully Unstaked NFT`, {
type: "success",
transition: "zoom",
timeout: 5000,
showIcon: true,
});
}
if (alertIndex.value == nfts.length) {
alertIndex.value = 0;
wallet.staking.value = false;
}
wallet.fetchNFTs();
},
});
}
catch (e) {
wallet.staking.value = false;
nfts.forEach((nft) => nft.isStaking = false)
}
} else {
const nfts = wallet.unstakedNFTs.value.filter(stakedNFT => stakedNFT.isSelected);
nfts.forEach((nft) => nft.isStaking = true)
wallet.staking.value = true;
try {
await stakeNFT(connection, anchorWallet.value, {
stakePoolId: stakePoolID,
nfts: nfts,
callback: () => {
alertIndex.value ;
if (nfts.length === 1) {
createToast("Successfully Staked NFT", {
type: "success",
transition: "zoom",
timeout: 5000,
showIcon: true,
});
}
else {
createToast(`${alertIndex.value}/${nfts.length} Successfully Staked NFT`, {
type: "success",
transition: "zoom",
timeout: 5000,
showIcon: true,
});
}
if (alertIndex.value == nfts.length) {
alertIndex.value = 0;
wallet.staking.value = false;
}
wallet.fetchNFTs();
}
})
}
catch (e) {
wallet.staking.value = false;
nfts.forEach((nft) => nft.isStaking = false)
}
}
await wallet.fetchNFTs();
}
}
</script>
CodePudding user response:
After hours and hours of trying I found out that I just had to remove the
getNFTNumber(nft.name)
function from my <NFTPane>
Component