import BN from 'bn.js'; import { AccountMeta, PublicKey, SystemProgram, TransactionInstruction } from '@solana/web3.js'; import { ADDRESS_LOOKUP_TABLE_PROGRAM_ID, BASKETS_V3_PROGRAM_ID, PYTHNET_CUSTODY_PRICE_USDC_ACCOUNT, PYTHNET_CUSTODY_PRICE_WSOL_ACCOUNT } from '../../constants'; import { getGlobalConfigPda, getLookupTableInfoAccount } from '../pda'; const CREATE_BASKET_LOOKUP_TABLES_DISCRIMINATOR = Buffer.from([227,98,152,128,87,46,244,99]); const EXTEND_BASKET_LOOKUP_TABLES_DISCRIMINATOR = Buffer.from([98, 129, 153, 127, 181, 160, 117, 74]); const OVERWRITE_BASKET_LOOKUP_TABLES_DISCRIMINATOR = Buffer.from([197, 116, 189, 147, 222, 188, 6, 165]); const CLOSE_DEACTIVATED_LOOKUP_TABLE_DISCRIMINATOR = Buffer.from([19, 4, 214, 20, 26, 43, 71, 233]); export function createBasketLookupTablesInstruction(params: { signer: PublicKey; basket: PublicKey; oldTempLookupTable0: PublicKey; oldTempLookupTable1: PublicKey; newTempLookupTable0: PublicKey; newTempLookupTable1: PublicKey; slot: number; }): TransactionInstruction { const { signer, basket, oldTempLookupTable0, oldTempLookupTable1, newTempLookupTable0, newTempLookupTable1, slot, } = params; const globalConfig = getGlobalConfigPda(); const hasOldTemp = !oldTempLookupTable0.equals(PublicKey.default) && !oldTempLookupTable1.equals(PublicKey.default); const data = Buffer.concat([ CREATE_BASKET_LOOKUP_TABLES_DISCRIMINATOR, Buffer.from(new BN(slot).toArray("le", 8)), ]); const keys: AccountMeta[] = [ { pubkey: signer, isSigner: true, isWritable: true }, { pubkey: basket, isSigner: false, isWritable: true }, { pubkey: globalConfig, isSigner: false, isWritable: false }, { pubkey: hasOldTemp ? oldTempLookupTable0 : PYTHNET_CUSTODY_PRICE_USDC_ACCOUNT, isSigner: false, isWritable: true }, { pubkey: hasOldTemp ? oldTempLookupTable1 : PYTHNET_CUSTODY_PRICE_WSOL_ACCOUNT, isSigner: false, isWritable: true }, { pubkey: newTempLookupTable0, isSigner: false, isWritable: true }, { pubkey: newTempLookupTable1, isSigner: false, isWritable: true }, ]; if (hasOldTemp) { keys.push( { pubkey: getLookupTableInfoAccount(oldTempLookupTable0), isSigner: false, isWritable: true }, { pubkey: getLookupTableInfoAccount(oldTempLookupTable1), isSigner: false, isWritable: true }, ); } else { keys.push( { pubkey: BASKETS_V3_PROGRAM_ID, isSigner: false, isWritable: false }, { pubkey: BASKETS_V3_PROGRAM_ID, isSigner: false, isWritable: false }, ); } keys.push( { pubkey: ADDRESS_LOOKUP_TABLE_PROGRAM_ID, isSigner: false, isWritable: false }, { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, ); return new TransactionInstruction({ keys, programId: BASKETS_V3_PROGRAM_ID, data, }); } export function extendBasketLookupTablesIx( params: { signer: PublicKey; basket: PublicKey; tempLookupTable0: PublicKey; tempLookupTable1: PublicKey; additionalAccounts: PublicKey[]; }): TransactionInstruction { const keys = [ { pubkey: params.signer, isWritable: true, isSigner: true }, { pubkey: params.basket, isWritable: true, isSigner: false }, { pubkey: params.tempLookupTable0, isWritable: true, isSigner: false }, { pubkey: params.tempLookupTable1, isWritable: true, isSigner: false }, { pubkey: ADDRESS_LOOKUP_TABLE_PROGRAM_ID, isWritable: false, isSigner: false }, { pubkey: SystemProgram.programId, isWritable: false, isSigner: false }, ...params.additionalAccounts.map(pubkey => ({pubkey, isWritable: false, isSigner: false})), ]; return new TransactionInstruction({ keys, programId: BASKETS_V3_PROGRAM_ID, data: EXTEND_BASKET_LOOKUP_TABLES_DISCRIMINATOR, }); } export function overwriteBasketLookupTablesIx( params: { signer: PublicKey; basket: PublicKey; tempLookupTable0: PublicKey; tempLookupTable1: PublicKey; activeLookupTable0: PublicKey; activeLookupTable1: PublicKey; }): TransactionInstruction { const keys = [ { pubkey: params.signer, isWritable: true, isSigner: true }, { pubkey: params.basket, isWritable: true, isSigner: false }, { pubkey: params.tempLookupTable0, isWritable: true, isSigner: false }, { pubkey: params.tempLookupTable1, isWritable: true, isSigner: false }, { pubkey: params.activeLookupTable0, isWritable: true, isSigner: false }, { pubkey: params.activeLookupTable1, isWritable: true, isSigner: false }, { pubkey: getLookupTableInfoAccount(params.activeLookupTable0), isWritable: true, isSigner: false }, { pubkey: getLookupTableInfoAccount(params.activeLookupTable1), isWritable: true, isSigner: false }, { pubkey: ADDRESS_LOOKUP_TABLE_PROGRAM_ID, isWritable: false, isSigner: false }, { pubkey: SystemProgram.programId, isWritable: false, isSigner: false }, ]; return new TransactionInstruction({ keys, programId: BASKETS_V3_PROGRAM_ID, data: OVERWRITE_BASKET_LOOKUP_TABLES_DISCRIMINATOR, }); } export function closeDeactivatedLookupTableIx(params: { rentPayer: PublicKey, basket: PublicKey, lookupTable: PublicKey }): TransactionInstruction { let lookupTableInfo = getLookupTableInfoAccount(params.lookupTable); const keys = [ { pubkey: params.rentPayer, isWritable: true, isSigner: false }, { pubkey: params.basket, isWritable: true, isSigner: false }, { pubkey: params.lookupTable, isWritable: true, isSigner: false }, { pubkey: lookupTableInfo, isWritable: true, isSigner: false }, { pubkey: ADDRESS_LOOKUP_TABLE_PROGRAM_ID, isWritable: false, isSigner: false }, { pubkey: SystemProgram.programId, isWritable: false, isSigner: false }, ]; return new TransactionInstruction({ keys, programId: BASKETS_V3_PROGRAM_ID, data: CLOSE_DEACTIVATED_LOOKUP_TABLE_DISCRIMINATOR, }); }