import BN from 'bn.js'; import { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID } from '@solana/spl-token'; import { PublicKey, SystemProgram, SYSVAR_INSTRUCTIONS_PUBKEY, SYSVAR_RENT_PUBKEY, TransactionInstruction } from '@solana/web3.js'; import { BASKETS_V3_PROGRAM_ID } from '../../constants'; import { getAta, getBasketFeesPda, getBountyVaultPda, getGlobalConfigPda, getRebalanceIntentPda, getRentPayerPda } from '../pda'; const CREATE_REBALANCE_INTENT_DISCRIMINATOR = Buffer.from([120, 80, 245, 123, 212, 149, 163, 47]); const RESIZE_REBALANCE_INTENT_HANDLER = Buffer.from([71, 204, 243, 183, 209, 118, 111, 94]); const INIT_REBALANCE_INTENT_DISCRIMINATOR = Buffer.from([127, 215, 41, 110, 244, 179, 131, 7]); const CANCEL_REBALANCE_DISCRIMINATOR = Buffer.from([51, 236, 71, 57, 141, 130, 39, 151]); export function createRebalanceIntentIx(params: { signer: PublicKey; owner: PublicKey; basket: PublicKey; }): TransactionInstruction { const { signer, owner, basket } = params; const rebalanceIntent = getRebalanceIntentPda(basket, owner); const rentPayerPda = getRentPayerPda(); const globalConfig = getGlobalConfigPda(); const keys = [ { pubkey: signer, isSigner: true, isWritable: true }, { pubkey: owner, isSigner: false, isWritable: true }, { pubkey: basket, isSigner: false, isWritable: true }, { pubkey: rebalanceIntent, isSigner: false, isWritable: true }, { pubkey: rentPayerPda, isSigner: false, isWritable: true }, { pubkey: globalConfig, isSigner: false, isWritable: false }, { pubkey: SYSVAR_INSTRUCTIONS_PUBKEY, isSigner: false, isWritable: false }, { pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false }, { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, ]; return new TransactionInstruction({ keys, programId: BASKETS_V3_PROGRAM_ID, data: CREATE_REBALANCE_INTENT_DISCRIMINATOR, }); } export function resizeRebalanceIntentIx( rebalanceIntent: PublicKey ): TransactionInstruction { const data = RESIZE_REBALANCE_INTENT_HANDLER; const keys = [ { pubkey: rebalanceIntent, isSigner: false, isWritable: true} ]; return new TransactionInstruction({ keys, programId: BASKETS_V3_PROGRAM_ID, data }); } export function initRebalanceIntentIx(params: { signer: PublicKey, owner: PublicKey, basket: PublicKey, basketTokenMint: PublicKey, rebalanceIntentRentPayer: PublicKey, bountyMint: PublicKey, rebalanceType: number, // u8 basketRebalanceIntent: PublicKey | undefined, rebalanceSlippageBps: number, // u16 perTradeRebalanceSlippageBps: number, // u16 executionStartTime: number, // u64 minBountyAmount: number, // u64 maxBountyAmount: number, // u64 withdrawParamsBurnAmount?: number, // u64 withdrawParamsTokenMintsHash?: number[], // length 32 withdrawParamsKeepTokensBitmask?: BN, // u128 withdrawParamsKeepAllTokens?: number, // u8 }): TransactionInstruction { const { signer, owner, basket, basketTokenMint, rebalanceIntentRentPayer, bountyMint, rebalanceType, rebalanceSlippageBps, perTradeRebalanceSlippageBps, executionStartTime, minBountyAmount, maxBountyAmount, withdrawParamsBurnAmount = 0, withdrawParamsTokenMintsHash = new Array(32).fill(0), withdrawParamsKeepTokensBitmask = new BN(0), withdrawParamsKeepAllTokens = 0, basketRebalanceIntent, } = params; const rebalanceIntent = getRebalanceIntentPda(basket, owner); const rentPayerPda = getRentPayerPda(); const globalConfig = getGlobalConfigPda(); const bountyVault = getBountyVaultPda(); const basketFeesPda = getBasketFeesPda(basket); const signerBasketAta = getAta(signer, basketTokenMint); const signerBountyAta = getAta(signer, bountyMint); const bountyVaultAta = getAta(bountyVault, bountyMint); const basketFeesAta = getAta(basketFeesPda, basketTokenMint); const data = Buffer.concat([ INIT_REBALANCE_INTENT_DISCRIMINATOR, rebalanceIntentRentPayer.toBuffer(), Buffer.from([rebalanceType]), Buffer.from(new BN(rebalanceSlippageBps).toArray("le", 2)), Buffer.from(new BN(perTradeRebalanceSlippageBps).toArray("le", 2)), Buffer.from(new BN(executionStartTime).toArray("le", 8)), Buffer.from(new BN(minBountyAmount).toArray("le", 8)), Buffer.from(new BN(maxBountyAmount).toArray("le", 8)), Buffer.from(new BN(withdrawParamsBurnAmount).toArray("le", 8)), Buffer.from(withdrawParamsTokenMintsHash), Buffer.from(withdrawParamsKeepTokensBitmask.toArray("le", 16)), Buffer.from([withdrawParamsKeepAllTokens]), ]); const keys = [ { pubkey: signer, isSigner: true, isWritable: true }, { pubkey: owner, isSigner: false, isWritable: true }, { pubkey: basket, isSigner: false, isWritable: true }, { pubkey: rebalanceIntent, isSigner: false, isWritable: true }, { pubkey: rentPayerPda, isSigner: false, isWritable: true }, { pubkey: basketTokenMint, isSigner: false, isWritable: true }, { pubkey: signerBasketAta, isSigner: false, isWritable: true }, { pubkey: globalConfig, isSigner: false, isWritable: false }, { pubkey: bountyMint, isSigner: false, isWritable: false }, { pubkey: signerBountyAta, isSigner: false, isWritable: true }, { pubkey: bountyVault, isSigner: false, isWritable: true }, { pubkey: bountyVaultAta, isSigner: false, isWritable: true }, { pubkey: basketFeesPda, isSigner: false, isWritable: true }, { pubkey: basketFeesAta, isSigner: false, isWritable: true }, { pubkey: basketRebalanceIntent ? basketRebalanceIntent : BASKETS_V3_PROGRAM_ID, isSigner: false, isWritable: basketRebalanceIntent ? true : false }, { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, { pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, ]; return new TransactionInstruction({ keys, programId: BASKETS_V3_PROGRAM_ID, data, }); } export function cancelRebalanceIx(params: { keeper: PublicKey, basket: PublicKey, rebalanceIntent: PublicKey, }): TransactionInstruction { const { keeper, basket, rebalanceIntent } = params; const globalConfig = getGlobalConfigPda(); const keys = [ { pubkey: keeper, isSigner: true, isWritable: true }, { pubkey: basket, isSigner: false, isWritable: true }, { pubkey: rebalanceIntent, isSigner: false, isWritable: true }, { pubkey: globalConfig, isSigner: false, isWritable: false }, ]; return new TransactionInstruction({ keys, programId: BASKETS_V3_PROGRAM_ID, data: CANCEL_REBALANCE_DISCRIMINATOR, }); }