Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

combining cooldown, unstake and withdraw into a bundle tx #97

Open
rashidkhokhar98 opened this issue May 30, 2022 · 4 comments
Open

combining cooldown, unstake and withdraw into a bundle tx #97

rashidkhokhar98 opened this issue May 30, 2022 · 4 comments

Comments

@rashidkhokhar98
Copy link

we had it working in the previous commit but now with the latest, unable to comprehend much. would be much help if someone can guide if its still possible :)

@Fahad-pnw
Copy link

having the same issue, anybody been able to figure?

@ghost
Copy link

ghost commented Jun 21, 2022

Can someone shares some code for combining cooldown, unstake and withdraw into a bundle tx? Thanks in advance.

@ghost
Copy link

ghost commented Jun 22, 2022

Thank you @johnwinsor for sharing. If one transaction with multiple istructions will be better.

@ghost
Copy link

ghost commented Jun 23, 2022

Made it work with one transaction:

when you want to unske a nft, you need unstake,unstake(this is for ending the cooldown),withdraw and stake 4 instructions. but if the vault is empty, don't stake, otherwise it will give a error.

action part:

let ins1 = farmerStatus === 'unstaked' ? [] : await farmClient.insOfUnstake(farmPublicKey, farmAccount.bank, 
farmerAccount.identity, farmerAccount.vault, farmAccount.rewardA.rewardMint, farmAccount.rewardB.rewardMint);
		let ins2 = await bankClient.insOfWithdraw(farmAccount.bank, farmerAccount.vault, new solweb3.PublicKey(nft.metaOnchain.mint));
		let ins3 = stakedNfts.length === 1 ? [] : await farmClient.insOfStake(farmPublicKey, farmerAccount.identity);
	
		let tx = new solweb3.Transaction({
			feePayer: wallet.publicKey,
			recentBlockhash: (await connection.getRecentBlockhash()).blockhash,
		}).add(...[...ins1, ...ins2, ...ins3]);
	
		const signed = await wallet.signTransaction(tx)
		await connection.sendRawTransaction(signed.serialize());

In your farmClient:

async insOfUnstake(farm: solweb3.PublicKey, bank: solweb3.PublicKey, farmerIdentity: solweb3.Signer, vault: solweb3.PublicKey, rewardAMint: solweb3.PublicKey, rewardBMint: solweb3.PublicKey, willBeEmpty: boolean) {
	const identityPk: solweb3.PublicKey = farmerIdentity.publicKey ? farmerIdentity.publicKey : (farmerIdentity as any);
	try {
		const [farmer, bumpFarmer] = await findFarmerPDA(farm, identityPk);
		const [farmAuth, bumpAuth] = await findFarmAuthorityPDA(farm);
		const [farmTreasury, bumpTreasury] = await findFarmTreasuryPDA(farm);
		const endStaking = this.farmProgram.instruction.unstake(bumpAuth, bumpTreasury, bumpFarmer, false, {
			accounts: {
				farm: farm,
				farmer: farmer,
				farmTreasury: farmTreasury,
				identity: identityPk,
				bank: bank,
				vault: vault,
				farmAuthority: farmAuth,
				gemBank: this.bankProgram.programId,
				systemProgram: solweb3.SystemProgram.programId,
				feeAcc: feeAccount
			},
			signers: [],
		});

		const [potA, potABump] = await findRewardsPotPDA(farm, rewardAMint);
		const [potB, potBBump] = await findRewardsPotPDA(farm, rewardBMint);
		const rewardADestination = await this.findATA(rewardAMint, this.wallet.publicKey);
		const rewardBDestination = await this.findATA(rewardBMint, this.wallet.publicKey);
		const rewards = this.farmProgram.instruction.claim(bumpAuth, bumpFarmer, potABump, potBBump, {
			accounts: {
				farm,
				farmAuthority: farmAuth,
				farmer,
				identity: identityPk,
				rewardAPot: potA,
				rewardAMint,
				rewardADestination,
				rewardBPot: potB,
				rewardBMint,
				rewardBDestination,
				tokenProgram: spltok.TOKEN_PROGRAM_ID,
				associatedTokenProgram: spltok.ASSOCIATED_TOKEN_PROGRAM_ID,
				systemProgram: solweb3.SystemProgram.programId,
				rent: solweb3.SYSVAR_RENT_PUBKEY,
			},
			signers: [],
		});
		return [endStaking, endStaking, rewards];
	}
	catch(e) {
		console.log(e);
	}
}
async insOfStake(farm: solweb3.PublicKey, farmerIdentity: solweb3.Signer) {
	try {
		const identityPk: solweb3.PublicKey = farmerIdentity.publicKey ? farmerIdentity.publicKey : (farmerIdentity as any);
		const farmAcc = await this.fetchFarmAcc(farm);
		const [farmer, farmerBump] = await findFarmerPDA(farm, this.wallet.publicKey);
		const [vault, vaultBump] = await findVaultPDA(farmAcc.bank, identityPk);
		const [farmAuth, farmAuthBump] = await findFarmAuthorityPDA(farm);

		return [this.farmProgram.instruction.stake(farmAuthBump, farmerBump, {
			accounts: {
				farm,
				farmer,
				identity: identityPk,
				bank: farmAcc.bank,
				vault,
				farmAuthority: farmAuth,
				gemBank: this.bankProgram.programId,
				feeAcc: feeAccount,
				systemProgram: solweb3.SystemProgram.programId,
			},
			signers: [],
		})];
	}
	catch(e) {
		console.log(e);
	}
}

In your backClient:

async insOfWithdraw(bank: solweb3.PublicKey, vault: solweb3.PublicKey, gemMint: solweb3.PublicKey) {
	try {
		var vaultOwner: solweb3.PublicKey = this.wallet.publicKey;
		var receiver: solweb3.PublicKey = this.wallet.publicKey;

		const [gemBox, gemBoxBump] = await findGemBoxPDA(vault, gemMint);
		const [GDR, GDRBump] = await findGdrPDA(vault, gemMint);
		const [vaultAuth, vaultAuthBump] = await findVaultAuthorityPDA(vault);
		const [gemRarity, gemRarityBump] = await findRarityPDA(bank, gemMint);
		const gemDestination = await this.findATA(gemMint, receiver);

		return [this.bankProgram.instruction.withdrawGem(vaultAuthBump, gemBoxBump, GDRBump, gemRarityBump, new BN(1), {
			accounts: {
				bank,
				vault,
				owner: vaultOwner,
				authority: vaultAuth,
				gemBox,
				gemDepositReceipt: GDR,
				gemDestination,
				gemMint,
				gemRarity,
				receiver,
				tokenProgram: spltok.TOKEN_PROGRAM_ID,
				associatedTokenProgram: spltok.ASSOCIATED_TOKEN_PROGRAM_ID,
				systemProgram: solweb3.SystemProgram.programId,
				rent: solweb3.SYSVAR_RENT_PUBKEY,
			},
			signers: []
		})];
	}
	catch(e) {
		console.log(e);
	}
}

Tested, it is working for me. Only one wallet confirmation is needed, otherwise the wallet atleast popup 3 times to let you to confirm.

  • solweb3 just a allias of webs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants