recipe.ts•2.85 kB
import { Connection, PublicKey } from '@solana/web3.js';
import { Program } from '@project-serum/anchor';
export interface RecipeAnalysis {
  collection: string;
  name: string;
  uri: string;
  max: number;
  min: number;
  amount: number;
  feeAmountCapture: number;
  feeAmountRelease: number;
  solFeeAmountCapture: number;
  solFeeAmountRelease: number;
  path: number;
  count: number;
  isValid: boolean;
  issues: string[];
}
export class RecipeService {
  constructor(
    private connection: Connection,
    private program: Program
  ) {}
  async analyzeRecipe(collectionAddress: string): Promise<RecipeAnalysis> {
    try {
      const collection = new PublicKey(collectionAddress);
      
      // Derive recipe PDA
      const [recipePda] = PublicKey.findProgramAddressSync(
        [Buffer.from("recipe"), collection.toBuffer()],
        this.program.programId
      );
      // Fetch recipe account data
      const recipeAccount = await this.program.account.recipeV1.fetch(recipePda);
      
      const issues: string[] = [];
      // Validate recipe configuration
      if (recipeAccount.max.toNumber() <= recipeAccount.min.toNumber()) {
        issues.push("Max value must be greater than min value");
      }
      if (recipeAccount.amount.toNumber() <= 0) {
        issues.push("Amount must be greater than 0");
      }
      // Check fee configuration
      if (recipeAccount.feeAmountCapture.toNumber() < 0 || recipeAccount.feeAmountRelease.toNumber() < 0) {
        issues.push("Fee amounts cannot be negative");
      }
      if (recipeAccount.solFeeAmountCapture.toNumber() < 0 || recipeAccount.solFeeAmountRelease.toNumber() < 0) {
        issues.push("SOL fee amounts cannot be negative");
      }
      return {
        collection: collectionAddress,
        name: recipeAccount.name,
        uri: recipeAccount.uri,
        max: recipeAccount.max.toNumber(),
        min: recipeAccount.min.toNumber(),
        amount: recipeAccount.amount.toNumber(),
        feeAmountCapture: recipeAccount.feeAmountCapture.toNumber(),
        feeAmountRelease: recipeAccount.feeAmountRelease.toNumber(),
        solFeeAmountCapture: recipeAccount.solFeeAmountCapture.toNumber(),
        solFeeAmountRelease: recipeAccount.solFeeAmountRelease.toNumber(),
        path: recipeAccount.path,
        count: recipeAccount.count.toNumber(),
        isValid: issues.length === 0,
        issues
      };
    } catch (error: any) {
      return {
        collection: collectionAddress,
        name: "",
        uri: "",
        max: 0,
        min: 0,
        amount: 0,
        feeAmountCapture: 0,
        feeAmountRelease: 0,
        solFeeAmountCapture: 0,
        solFeeAmountRelease: 0,
        path: 0,
        count: 0,
        isValid: false,
        issues: [`Failed to analyze recipe: ${error.message}`]
      };
    }
  }
}