import { AnchorProvider, BorshAccountsCoder, Program, utils } from '@project-serum/anchor'; import { SignerWallet } from '@saberhq/solana-contrib'; import type { Connection } from '@solana/web3.js'; import { Keypair, PublicKey } from '@solana/web3.js'; import type { AccountData } from '../../types'; import type { BLAZE_PROGRAM, BlazeData, EntrantsData, EntrantsDataRaw, IdentifierData } from './constants'; import { BLAZE_ADDRESS, BLAZE_IDL, BLAZE_PREFIX, BLAZE_PROJECT_ID_OFFSET, ENTRANTS_PREFIX } from './constants'; import { findIdentifierId } from './pda'; const getProgram = (connection: Connection) => { const provider = new AnchorProvider( connection, new SignerWallet(Keypair.generate()), {} ); return new Program(BLAZE_IDL, BLAZE_ADDRESS, provider); }; export const getBlaze = async ( connection: Connection, blazeId: PublicKey ): Promise> => { const program = getProgram(connection); const parsed = await program.account.blaze.fetch(blazeId); return { parsed, pubkey: blazeId }; }; export const getBlazes = async ( connection: Connection, blazeIds: PublicKey[] ): Promise[]> => { const program = getProgram(connection); const blazes = (await program.account.blaze.fetchMultiple( blazeIds )) as BlazeData[]; return blazes.map((tm, i) => ({ parsed: tm, // eslint-disable-next-line @typescript-eslint/no-non-null-assertion pubkey: blazeIds[i]! })); }; export const getAllBlazes = async ( connection: Connection ): Promise[]> => { if (!connection) return []; const programAccounts = await connection.getProgramAccounts(BLAZE_ADDRESS, { filters: [ { memcmp: { offset: 0, bytes: utils.bytes.bs58.encode( BorshAccountsCoder.accountDiscriminator(BLAZE_PREFIX) ) } } ] }); const blazeDatas: AccountData[] = []; const coder = new BorshAccountsCoder(BLAZE_IDL); programAccounts.forEach(account => { try { const blazeData: BlazeData = coder.decode( BLAZE_PREFIX, account.account.data ); if (blazeData) { blazeDatas.push({ ...account, parsed: blazeData }); } // eslint-disable-next-line no-empty } catch (e) {} }); return blazeDatas.sort((a, b) => a.pubkey.toBase58().localeCompare(b.pubkey.toBase58()) ); }; export const getIdentifier = async ( connection: Connection ): Promise> => { const program = getProgram(connection); const [identifierId] = await findIdentifierId(); const parsed = await program.account.identifier.fetch(identifierId); return { parsed, pubkey: identifierId }; }; export const getBlazesByProjectId = async ( connection: Connection, projectId: PublicKey ): Promise[]> => { if (!connection) return []; const programAccounts = await connection.getProgramAccounts(BLAZE_ADDRESS, { filters: [ { memcmp: { offset: 0, bytes: utils.bytes.bs58.encode( BorshAccountsCoder.accountDiscriminator(BLAZE_PREFIX) ) } }, { memcmp: { offset: BLAZE_PROJECT_ID_OFFSET, bytes: projectId.toBase58() } } ] }); const blazeDatas: AccountData[] = []; const coder = new BorshAccountsCoder(BLAZE_IDL); programAccounts.forEach(account => { try { const blazeData: BlazeData = coder.decode( BLAZE_PREFIX, account.account.data ); if (blazeData) { blazeDatas.push({ ...account, parsed: blazeData }); } // eslint-disable-next-line no-empty } catch (e) {} }); return blazeDatas.sort((a, b) => a.pubkey.toBase58().localeCompare(b.pubkey.toBase58()) ); }; export const getAllEntrants = async ( connection: Connection ): Promise[]> => { if (!connection) return []; const programAccounts = await connection.getProgramAccounts(BLAZE_ADDRESS, { filters: [ { memcmp: { offset: 0, bytes: utils.bytes.bs58.encode( BorshAccountsCoder.accountDiscriminator(ENTRANTS_PREFIX) ) } } ] }); const entrantsDatas: AccountData[] = []; const coder = new BorshAccountsCoder(BLAZE_IDL); programAccounts.forEach(account => { try { const entrantsDataRaw: EntrantsDataRaw = coder.decode( ENTRANTS_PREFIX, account.account.data ); if (entrantsDataRaw) { const entrants: PublicKey[] = []; const entrantsFieldData = account.account.data.subarray(8 + 4 + 4); for (let i = 0; i < entrantsDataRaw.total; i++) { entrants.push( new PublicKey(entrantsFieldData.slice(i * 32, (i + 1) * 32)) ); } entrantsDatas.push({ ...account, parsed: { ...entrantsDataRaw, entrants } }); } // eslint-disable-next-line no-empty } catch (e) {} }); return entrantsDatas.sort((a, b) => a.pubkey.toBase58().localeCompare(b.pubkey.toBase58()) ); }; export const getEntrants = async ( connection: Connection, entrantsId: PublicKey ): Promise | null | undefined> => { if (!connection) return null; const programAccounts = await connection.getProgramAccounts(BLAZE_ADDRESS, { filters: [ { memcmp: { offset: 0, bytes: utils.bytes.bs58.encode( BorshAccountsCoder.accountDiscriminator(ENTRANTS_PREFIX) ) } } ] }); const coder = new BorshAccountsCoder(BLAZE_IDL); const account = programAccounts.find( account => account.pubkey.toBase58() === entrantsId.toBase58() ); if (!account) return null; try { const entrantsDataRaw: EntrantsDataRaw = coder.decode( ENTRANTS_PREFIX, account.account.data ); if (entrantsDataRaw) { const entrants: PublicKey[] = []; const entrantsFieldData = account.account.data.subarray(8 + 4 + 4); for (let i = 0; i < entrantsDataRaw.total; i++) { entrants.push( new PublicKey(entrantsFieldData.slice(i * 32, (i + 1) * 32)) ); } return { ...account, parsed: { ...entrantsDataRaw, entrants } }; } // eslint-disable-next-line no-empty } catch (e) {} };