import { Connection , PublicKey } from '@solana/web3.js' ; import { create } from 'superstruct' ; export const BPF_UPGRADE_LOADER_ID = new PublicKey ( 'BPFLoaderUpgradeab1e11111111111111111111111' ) ; import { type , number , nullable , Infer } from 'superstruct' ; import { coerce , instance , string } from 'superstruct' ; export const PublicKeyFromString = coerce ( instance ( PublicKey ) , string ( ) , value => new PublicKey ( value ) ) ; export type ProgramDataAccountInfo = Infer < typeof ProgramDataAccountInfo > ; export const ProgramDataAccountInfo = type ( { authority : nullable ( PublicKeyFromString ) , slot : number ( ) , } ) ; export async function getProgramDataAddress ( programId ) { const [ programDataAddress ] = await PublicKey . findProgramAddress ( [ programId . toBuffer ( ) ] , BPF_UPGRADE_LOADER_ID ) ; return programDataAddress ; } export async function getProgramDataAccount ( connection , programId ) { const programDataAddress = await getProgramDataAddress ( programId ) ; const account = await connection . getParsedAccountInfo ( programDataAddress ) ; if ( ! account || ! account . value ) { throw new Error ( `Program data account ${ programDataAddress . toBase58 ( ) } for program ${ programId . toBase58 ( ) } not found` ) ; } const accountInfo = account . value ; if ( ! ( 'parsed' in accountInfo . data && accountInfo . data . program === 'bpf-upgradeable-loader' ) ) { throw new Error ( `Invalid program data account ${ programDataAddress . toBase58 ( ) } for program ${ programId . toBase58 ( ) }` ) ; } let programData = create ( accountInfo . data . parsed . info , ProgramDataAccountInfo ) ; return programData ; }