import { KeyedAccountInfo, PublicKey, SystemProgram } from '@solana/web3.js'; import { Account, AccountStatic, AsyncSigner, DecodedAccountData, InstructionReturn, arrayDeepEquals, decodeAccount, staticImplements, } from '@staratlas/data-source'; import { KeyIndexInput } from './common'; import { CraftingIDL, CraftingIDLProgram, RecipeCategoryAccount, } from './constants'; /** * Checks equality between 2 Recipe Category Accounts * @param data1 - First Recipe Category Accounts * @param data2 - Second Recipe Category Account * @returns boolean */ export function recipeCategoryDataEquals( data1: RecipeCategoryAccount, data2: RecipeCategoryAccount, ): boolean { return ( data1.version === data2.version && data1.domain.equals(data2.domain) && data1.recipeCount === data2.recipeCount && arrayDeepEquals( data1.namespace, data2.namespace, (data1, data2) => data1 === data2, ) ); } export interface RegisterRecipeCategoryInput { namespace: number[]; keyIndex: number; } @staticImplements>() export class RecipeCategory implements Account { static readonly ACCOUNT_NAME: NonNullable< CraftingIDL['accounts'] >[number]['name'] = 'recipeCategory'; static readonly MIN_DATA_SIZE: number = 8 + // discriminator 1 + // version 32 + // domain 32 + // creator 4 + // recipeCount 32; // namespace constructor(private _data: RecipeCategoryAccount, private _key: PublicKey) {} get data(): Readonly { return this._data; } get key(): PublicKey { return this._key; } /** * Register `RecipeCategory` * @param program - Crafting program * @param recipeCategory - the new crafting recipe category * @param key - Key authorized to use this instruction * @param profile - Profile Account with required Crafting Permissions * @param domain - the crafting domain * @param input - the input parameters * @returns InstructionReturn */ static registerRecipeCategory( program: CraftingIDLProgram, recipeCategory: AsyncSigner, key: AsyncSigner, profile: PublicKey, domain: PublicKey, input: RegisterRecipeCategoryInput, ): InstructionReturn { return async (funder) => [ { instruction: await program.methods .registerRecipeCategory(input) .accountsStrict({ key: key.publicKey(), profile, funder: funder.publicKey(), recipeCategory: recipeCategory.publicKey(), domain, systemProgram: SystemProgram.programId, }) .instruction(), signers: [key, funder, recipeCategory], }, ]; } /** * Deregister `RecipeCategory` * @param program - Crafting program * @param recipeCategory - the crafting recipe category * @param key - Key authorized to use this instruction * @param profile - Profile Account with required Crafting Permissions * @param fundsTo - receives rent refund * @param domain - the crafting domain * @param input - the input parameters * @returns InstructionReturn */ static deregisterRecipeCategory( program: CraftingIDLProgram, recipeCategory: PublicKey, key: AsyncSigner, profile: PublicKey, fundsTo: PublicKey | 'funder', domain: PublicKey, input: KeyIndexInput, ): InstructionReturn { return async (funder) => [ { instruction: await program.methods .deregisterRecipeCategory(input) .accountsStrict({ key: key.publicKey(), profile, fundsTo: fundsTo === 'funder' ? funder.publicKey() : fundsTo, recipeCategory, domain, systemProgram: SystemProgram.programId, }) .instruction(), signers: [key], }, ]; } static decodeData( account: KeyedAccountInfo, program: CraftingIDLProgram, ): DecodedAccountData { return decodeAccount(account, program, RecipeCategory); } }