import BN from 'bn.js'; import { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_2022_PROGRAM_ID, TOKEN_PROGRAM_ID } from '@solana/spl-token'; import { PublicKey, SystemProgram, TransactionInstruction } from '@solana/web3.js'; import { BASKETS_V3_PROGRAM_ID } from '../../constants'; import { getAta, getBasketFeesPda, getGlobalConfigPda, getRebalanceIntentPda } from '../pda'; const DEPOSIT_TOKENS_DISCRIMINATOR = Buffer.from([88, 92, 158, 219, 83, 71, 239, 164]); const LOCK_DEPOSITS_DISCRIMINATOR = Buffer.from([64, 238, 171, 198, 135, 253, 37, 9]); const MINT_BASKET_DISCRIMINATOR = Buffer.from([161, 207, 48, 45, 7, 156, 233, 143]); export function depositTokensIx(params: { owner: PublicKey; basket: PublicKey; contributions: {mint: PublicKey, amount: number}[]; // length 10 }): TransactionInstruction[] { const { owner, basket, contributions } = params; let rebalanceIntent = getRebalanceIntentPda(basket, owner); const discriminator = DEPOSIT_TOKENS_DISCRIMINATOR; let ixs: TransactionInstruction[] = []; let batch_size = 5; for (let i = 0; i < contributions.length; i += batch_size) { let batch_contributions = contributions.slice(i, i + batch_size); let amounts = batch_contributions.map((contribution) => contribution.amount); while (amounts.length < 10) amounts.push(0); const amountsBuffer = Buffer.concat( amounts.map((amount) => Buffer.from(new BN(amount).toArray("le", 8))) ); const data = Buffer.concat([discriminator, amountsBuffer]); const keys = [ { pubkey: owner, isSigner: true, isWritable: true }, { pubkey: basket, isSigner: false, isWritable: true }, { pubkey: rebalanceIntent, isSigner: false, isWritable: true }, { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, { pubkey: TOKEN_2022_PROGRAM_ID, isSigner: false, isWritable: false }, { pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, ]; // remaining accounts batch_contributions.forEach((contribution) => { let mint = contribution.mint; let ownerAta = getAta(owner, mint); let basketAta = getAta(basket, mint); keys.push({ pubkey: mint, isSigner: false, isWritable: false }); keys.push({ pubkey: ownerAta, isSigner: false, isWritable: true }); keys.push({ pubkey: basketAta, isSigner: false, isWritable: true }); }); ixs.push( new TransactionInstruction({ keys, programId: BASKETS_V3_PROGRAM_ID, data, }) ); } return ixs; } export function lockDepositsIx(params: { owner: PublicKey; basket: PublicKey; }): TransactionInstruction { const { owner, basket } = params; let rebalanceIntent = getRebalanceIntentPda(basket, owner); let globalConfig = getGlobalConfigPda(); const keys = [ { pubkey: params.owner, isSigner: true , isWritable: true}, { pubkey: rebalanceIntent, isSigner: false, isWritable: true }, { pubkey: globalConfig, isSigner: false, isWritable: false }, ]; return new TransactionInstruction({ keys, programId: BASKETS_V3_PROGRAM_ID, data: LOCK_DEPOSITS_DISCRIMINATOR, }); } export function mintBasketIx(params: { keeper: PublicKey; basket: PublicKey; basketTokenMint: PublicKey; buyer: PublicKey; basketRebalanceIntent?: PublicKey; }): TransactionInstruction { const { keeper, basket, basketTokenMint, buyer } = params; let rebalanceIntent = getRebalanceIntentPda(basket, buyer); let basketFees = getBasketFeesPda(basket); let globalConfig = getGlobalConfigPda(); let buyerBasketATA = getAta(buyer, basketTokenMint); let basketFeesAta = getAta(basketFees, basketTokenMint); const keys = [ { pubkey: keeper, isWritable: true, isSigner: true }, { pubkey: basket, isWritable: true, isSigner: false }, { pubkey: rebalanceIntent, isWritable: true, isSigner: false }, { pubkey: basketTokenMint, isWritable: true, isSigner: false }, { pubkey: buyer, isWritable: true, isSigner: false }, { pubkey: buyerBasketATA, isWritable: true, isSigner: false }, { pubkey: globalConfig, isWritable: false, isSigner: false }, { pubkey: basketFees, isWritable: true, isSigner: false }, { pubkey: basketFeesAta, isWritable: true, isSigner: false }, { pubkey: params.basketRebalanceIntent ?? BASKETS_V3_PROGRAM_ID, isWritable: params.basketRebalanceIntent ? true : false, isSigner: false }, { pubkey: TOKEN_PROGRAM_ID, isWritable: false, isSigner: false }, { pubkey: TOKEN_2022_PROGRAM_ID, isWritable: false, isSigner: false }, { pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isWritable: false, isSigner: false }, { pubkey: SystemProgram.programId, isWritable: false, isSigner: false }, ]; return new TransactionInstruction({ keys, programId: BASKETS_V3_PROGRAM_ID, data: MINT_BASKET_DISCRIMINATOR, }); }