import { randomBytes } from 'crypto'; import BN from 'bn.js'; import { getAssociatedTokenAddressSync } from '@solana/spl-token'; import { AddressLookupTableProgram, PublicKey } from '@solana/web3.js'; import { BASKETS_V3_PROGRAM_ID } from '../constants'; export const GLOBAL_CONFIG_SEED = Buffer.from("global_config"); export const BASKET_FEES_SEED = Buffer.from("basket_fees"); export const WITHDRAW_BASKET_FEES_SEED = Buffer.from("withdraw_basket_fees"); export const BASKET_SEED = Buffer.from("basket"); export const MINT_SEED = Buffer.from("mint"); export const RENT_PAYER_SEED = Buffer.from("rent_payer"); export const BOUNTY_VAULT_SEED = Buffer.from("bounty_vault"); export const REBALANCE_INTENT_SEED = Buffer.from("rebalance_intent"); export const TOKEN_METADATA_PROGRAM_ID = new PublicKey("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"); export function serializeString(input: string): Uint8Array { const utf8 = new TextEncoder().encode(input); const length = utf8.length; const out = new Uint8Array(4 + length); // encode length as little-endian u32 out[0] = length & 0xff; out[1] = (length >> 8) & 0xff; out[2] = (length >> 16) & 0xff; out[3] = (length >> 24) & 0xff; // copy utf8 bytes after the 4-byte length out.set(utf8, 4); return out; } export function getRandomSeed(): number[] { return Array.from(randomBytes(16)); } export function getBasketTokenMintPda(basketId: number) { return PublicKey.findProgramAddressSync([ MINT_SEED, new BN(basketId).toArrayLike(Buffer, "le", 8) ], BASKETS_V3_PROGRAM_ID)[0]; } export function getBasketState(mint: PublicKey) { return PublicKey.findProgramAddressSync([ BASKET_SEED, mint.toBuffer() ], BASKETS_V3_PROGRAM_ID)[0]; } export function getBountyVaultPda() { return PublicKey.findProgramAddressSync([ BOUNTY_VAULT_SEED, ], BASKETS_V3_PROGRAM_ID)[0]; } export function getBasketFeesPda(basket: PublicKey) { return PublicKey.findProgramAddressSync([ BASKET_FEES_SEED, basket.toBuffer() ], BASKETS_V3_PROGRAM_ID)[0]; } export function getWithdrawBasketFeesPda(basket: PublicKey, feeType: number) { return PublicKey.findProgramAddressSync([ WITHDRAW_BASKET_FEES_SEED, basket.toBuffer(), Buffer.from([feeType]) // u8, not u64 ], BASKETS_V3_PROGRAM_ID)[0]; } export function getGlobalConfigPda() { return PublicKey.findProgramAddressSync([ GLOBAL_CONFIG_SEED ], BASKETS_V3_PROGRAM_ID)[0]; } export function getRentPayerPda() { return PublicKey.findProgramAddressSync([ RENT_PAYER_SEED ], BASKETS_V3_PROGRAM_ID)[0]; } export function getIntentPda( basket: PublicKey, intentSeedArray: Uint8Array, editType: number, ) { return PublicKey.findProgramAddressSync([ basket.toBuffer(), intentSeedArray, Uint8Array.from([editType]), ], BASKETS_V3_PROGRAM_ID)[0]; } export function getRebalanceIntentPda( basket: PublicKey, owner: PublicKey, ) { return PublicKey.findProgramAddressSync([ REBALANCE_INTENT_SEED, basket.toBuffer(), owner.toBuffer(), ], BASKETS_V3_PROGRAM_ID)[0]; } export function getMetadataAccount( tokenMint: PublicKey ): PublicKey { return PublicKey.findProgramAddressSync( [ Buffer.from("metadata"), TOKEN_METADATA_PROGRAM_ID.toBuffer(), tokenMint.toBuffer(), ], TOKEN_METADATA_PROGRAM_ID )[0]; } export function getLookupTableAccount( creator: PublicKey, slot: number, ): PublicKey { const ixAndPubkey = AddressLookupTableProgram.createLookupTable({ authority: creator, recentSlot: slot, payer: creator, }); return ixAndPubkey[1]; } export function getLookupTableInfoAccount( lookupTable: PublicKey, ): PublicKey { return PublicKey.findProgramAddressSync([ lookupTable.toBuffer() ], BASKETS_V3_PROGRAM_ID)[0]; } export function getAta( wallet: PublicKey, tokenMint: PublicKey, tokenProgram?: PublicKey ): PublicKey { return getAssociatedTokenAddressSync(tokenMint, wallet, true, tokenProgram); }