Source

modules/CollectionManager.ts

import {
  CreateCollectionResponse,
  CreateCollectionParams,
  GetCollectionParams,
  GetAssetByCollectionParams,
  UpdateCollectionByContractAddressParams,
  CreateCollectionMetadataParams,
  CollectionDetailsResponseData,
  AssetListResponse,
  UpdateCollectionMetadataParams,
  CollectionListResponse,
  CollectionMetadataSchemaParams,
  AttributesResponse,
  OwnerAssetsCount,
  GetTotalAssetsByOwnerParams,
  CreateCollectionByApiKeyParams,
  UpdateCollectionByCollectionIdAndApiKeyParams,
  ValidateMetadataParams,
  ValidateMetadataResponse,
  GetCollectionByApiKeyParams,
  CollectionTypes
} from "./../types/CollectionTypes";
import { CollectionAPI } from "./../core/apis/collection.api";
import { APIResponseType } from "../types/APIResponseType";
import { CommonPaginateDataTypes } from "../types/CommonTypes";
import { EnvTypes, ProjectResponseData } from "../typesBundle";
import { ProjectAPI } from "../core/apis";

/**
 * Create CollectionManager module
 * @class CollectionManager
 * @param {EnvTypes} env Environment type (DEV / STAGING / PREPROD / PROD)
 * @example <caption>CollectionManager Instantiation</caption>
  const collectionManager = new CollectionManager(EnvTypes.STAGING);
 *
 */
export class CollectionManager {
  private collectionAPI: CollectionAPI;
  private projectAPI: ProjectAPI;

  constructor(env: EnvTypes) {
    this.collectionAPI = new CollectionAPI(env);
    this.projectAPI = new ProjectAPI(env);
  }

  /**
   * @summary Create collection data 
   * @param {CreateCollectionParams} payload Create collection request params (name / collectionImageUrl / description / contractAddress / metadataUrl)
   * @returns {CreateCollectionResponse} Collection details response
   * @throws {string} Exception: StarkKey is required
   * @throws {string} Exception: Name is required
   * @throws {string} Exception: ContractAddress is required
   * @throws {string} Exception: MetadataAPIUri is required
   * @throws {string} Exception: OwnerPublicKey is required
   * @throws {string} Exception: ProjectID is required
   * @throws {string} Exception: Create Collection failure with internal server error
   * @example <caption>Sample of createCollection({}) on Staging env</caption>
  
  const collectionManager: CollectionManager = new CollectionManager(EnvTypes.STAGING);

  const contractAddress: string = config.collection_contract_address;
  const metadataApiUrl: string = config.metadata_api_url;
  const publicKey: string = config.public_key;
  const projectId: number = config.project_id;
  const starkKey: string = config.stark_key;

  const params: CreateCollectionParams = {
    name: "Test Collection 1",
    description: "Collection Test with SDK",
    contractAddress: contractAddress,
    metadataApiUrl: metadataApiUrl,
    ownerPublicKey: publicKey,
    projectId: projectId,
    starkKey: starkKey,
  };

  console.log("Creating the collection...");
  const collectionResponse: CreateCollectionResponse = await collectionManager.createCollection(params);

  console.log("Created collection response:");
  console.log(JSON.stringify(collectionResponse, null, 2));
  */
  public async createCollection(payload: CreateCollectionParams): Promise<CreateCollectionResponse | undefined> {
    let createCollectionData: CreateCollectionResponse;
    if (!payload.starkKey) {
      throw new Error("StarkKey is required");
    }
    if (!payload.name) {
      throw new Error("Name is required");
    }
    if (!payload.contractAddress) {
      throw new Error("ContractAddress is required");
    }
    if (!payload.metadataApiUrl) {
      throw new Error("MetadataAPIUri is required");
    }
    if (!payload.ownerPublicKey) {
      throw new Error("OwnerPublicKey is required");
    }
    if (!payload.projectId) {
      throw new Error("ProjectId is required");
    }
    {
      try {
        const createCollectionRes = await this.collectionAPI.createCollection(
          payload
        );
        if (createCollectionRes?.status === "success") {
          createCollectionData = createCollectionRes?.data;
        } else {
          throw new Error("Create Collection failure with internal server error");
        }
      } catch (error) {
        throw new Error(error);
      }
    }
    return createCollectionData;
  }

  /**
   * @summary Get collection list
   * @param {GetCollectionParams} GetCollectionParams query collections params 
   * @returns {CommonPaginateDataTypes<CollectionListResponse[]>} Paginable collections data
   * @example <caption>Sample of getCollectionList({}) on Staging env</caption>
  
  const collectionManager: CollectionManager = new CollectionManager(EnvTypes.STAGING);

  const params: GetCollectionParams = {
    limit: 10,
    page: 1,
    isHot: true
  };

  console.log("Get the collection...");
  const collections: CommonPaginateDataTypes<CollectionListResponse[]> = await collectionManager.getCollectionList(params);

  console.log("List of collection response:");
  console.log(JSON.stringify(collections, null, 2));
   */
  public async getCollectionList(params?: GetCollectionParams): Promise<APIResponseType<CommonPaginateDataTypes<CollectionListResponse[]>> | undefined> {
    const collectionList = await this.collectionAPI.getCollectionList(params);
    return collectionList;
  }

  public async getCollections(params: GetCollectionByApiKeyParams): Promise<CollectionTypes[] | undefined> {
    if (!params.accountId) {
      throw new Error('Myria User ID is required');
    }

    if (!params.apiKey) {
      throw new Error('Developer API Key is required');
    }

    const reqProjects = await this.projectAPI.getProjectsByUserIDAndApiKey(params.accountId, params.apiKey);
    let listProjects: ProjectResponseData[] = [];

    if (reqProjects?.status === 'success') {
      listProjects = reqProjects.data as ProjectResponseData[] || [];
    }

    const listCollections: CollectionTypes[] = [];
    for (const project of listProjects) {
      // Get list projects
      const collectionResponseData = await this.projectAPI.getCollectionListByProjectId(project.id);

      if (collectionResponseData.status === 'success') {
        listCollections.push(...collectionResponseData.data.collections as CollectionTypes[]);
      } else {
        continue;
      }
    }

    return listCollections;
  }

  /**
   * @summary Get collection details by ID
   * @param {number} id unique ID of the collection 
   * @returns {CollectionDetailsResponseData} Collection details information data
   * @throws {string} Exception: Collection ID is required
   * @throws {string} Exception: Get collection by ID failed with internal server error
   * @example <caption>Sample of getCollectionById(collectionId) on Staging env</caption>
  
  const collectionManager: CollectionManager = new CollectionManager(EnvTypes.STAGING);

  const collectionId = 1;

  console.log("Get the collection...");
  const collectionData: CollectionDetailsResponseData = await collectionManager.getCollectionById(collectionId);
  console.log(JSON.stringify(collectionData, null, 2));
   
  */
  public async getCollectionById(
    id: number
  ): Promise<CollectionDetailsResponseData | undefined> {

    if (!id) {
      throw new Error("Collection ID is required");
    }

    const collectionResponse = await this.collectionAPI.getCollectionById(id);
    if (collectionResponse?.status !== 'success') {
      throw new Error("Get collection by ID failed with internal server error");
    }
    return collectionResponse.data;
  }

  /**
   * @summary Get collection metadata schema by smart contract address (deployed address of the collection)
   * @param {string} contractAddress The smart contract address of the collection
   * @returns {CollectionMetadataSchemaParams[]} List of metadata fields of the specific collection
   * @throws {string} Exception: Contract address is required
   * @example <caption>Sample of getCollectionMetadataByAddress(contractAddress) on Staging env</caption>
  
  const collectionManager: CollectionManager = new CollectionManager(EnvTypes.STAGING);

  const contractAddress = '0xFCB75a9De034b9DEff9aD1a12142c12E51665F97';

  console.log("Get the collection metadata...");
  const collectionMetadata: APIResponseType<CollectionMetadataSchemaParams[]> = await collectionManager.getCollectionMetadataByAddress(contractAddress);
  console.log(JSON.stringify(collectionMetadata, null, 2));
   */
  public async getCollectionMetadataByAddress(
    contractAddress: string
  ): Promise<APIResponseType<CollectionMetadataSchemaParams[]> | undefined> {
    if (!contractAddress) {
      throw new Error('Contract address is required')
    }
    const collectionByAddress = await this.collectionAPI.getCollectionMetadataByAddress(
      contractAddress
    );
    return collectionByAddress;
  }

  /**
   * @summary Create collection metadata schema by smart contract address (deployed address of the collection contract)
   * @param {string} contractAddress Smart contract address of the collection
   * @param {CreateCollectionMetadataParams} payload The metadata structure params
   * @returns {CollectionDetailsResponseData} List of metadata fields of the specific collection
   * @throws {string} Exception: Contract address is required
   * @throws {string} Exception: StarkKey is required
   * @throws {string} Exception: Key name of metadata is required
   * @throws {string} Exception: Internal server error
   * @example <caption>Sample of createCollectionMetadataByAddress(contractAddress, {}) on Staging env</caption>
  
  const collectionManager: CollectionManager = new CollectionManager(EnvTypes.STAGING);

  const contractAddress = '0xFCB75a9De034b9DEff9aD1a12142c12E51665F97';
  const payload: CreateCollectionMetadataParams = {
    metadata: [
      {
        name: 'rarity',
        type: 'string',
        filterable: true,
      },
      {
        name: 'power',
        type: 'string',
        filterable: true,
      },
      {
        name: 'level',
        type: 'enum',
        filterable: true,
      },
      {
        name: 'color',
        type: 'string',
        filterable: false,
      },
    ];
    starkKey: '0xFC....',
  };

  console.log("Get the collection metadata...");
  const collectionMetadata: CollectionDetailsResponseData = await collectionManager.createCollectionMetadataByAddress(contractAddress, payload);
  console.log(JSON.stringify(collectionMetadata, null, 2));
   */
  public async createCollectionMetadataByAddress(
    contractAddress: string,
    payload: CreateCollectionMetadataParams
  ): Promise<CollectionDetailsResponseData | undefined> {
    let collectionByAddress: any;

    if (!contractAddress) {
      throw new Error("Contract address is required");
    }

    if (!payload.starkKey) {
      throw new Error("StarkKey is required");
    }

    payload.metadata.forEach((data: any, index: number) => {
      if (!data.name) {
        throw new Error(`${index + 1}th item's name for metadata is required!`);
      }
    });

    try {
      collectionByAddress = await this.collectionAPI.createCollectionMetadataByAddress(
        contractAddress, payload
      );
      if (collectionByAddress?.status === "success") {
        collectionByAddress = collectionByAddress?.data;
      } else {
        throw new Error("Create Collection by smart contract address failure with internal server error");
      }
    } catch (error) {
      throw new Error(error);
    }
    return collectionByAddress;
  }

  /**
   * @summary Update metadata schema (change field key) by smart contract address
   * @param {string} contractAddress The unique smart contract address for the collection
   * @param {string} name The existing key property in the metadata schema (for example we have the property power, and we want to change to power_character)
   * @param {UpdateCollectionMetadataParams} payload The request params for Updated Metadata
   * @returns {CollectionDetailsResponseData} The collection details information (including new metadata updated...)
   * @throws {string} Exception: Internal server error
   * 
   * @example <caption>Sample of updateCollectionMetadataByAddress(contractAddress, name, {}) on Staging env</caption>
  
  const collectionManager: CollectionManager = new CollectionManager(EnvTypes.STAGING);

  const contractAddress = '0xFCB75a9De034b9DEff9aD1a12142c12E51665F97';
  const name = 'Rarity';
  const payload: UpdateCollectionMetadataParams = {
    name: 'Rarity_1',
    type: 'string',
    filterable: true,
    starkKey: '0x09af....'
  };

  console.log("Update the collection metadata by smart contract address...");
  const collectionData: CollectionDetailsResponseData = await collectionManager.updateCollectionMetadataByAddress(contractAddress, name, payload);
  console.log(JSON.stringify(collectionData, null, 2));
   */
  public async updateCollectionMetadataByAddress(
    contractAddress: string,
    name: string,
    payload: UpdateCollectionMetadataParams
  ): Promise<CollectionDetailsResponseData | undefined> {
    let collectionByAddress: any;
    if (this.validationParams({ contractAddress, name: payload.name, starkKey: payload.starkKey })) {
      try {
        collectionByAddress = await this.collectionAPI.updateCollectionMetadataByAddress(
          contractAddress, name, payload
        );
        if (collectionByAddress?.status === "success") {
          collectionByAddress = collectionByAddress?.data;
        } else {
          throw new Error("Update Collection Metadata by smart contract address failure due to internal server error");
        }
      } catch (error) {
        throw new Error(error);
      }
    }
    return collectionByAddress;
  }

  /**
   * @summary Get the collection by the public ID (uuid)
   * @param {string} publicId The unique public ID (UUID) of the collection
   * @returns {CollectionDetailsResponseData} Collection details information data (metadata schema, name, description, metadataUrl...)
   * @throws {string} Exception: The public ID is required
   * @example <caption>Sample of getCollectionByPublicId(publicId) on Staging env</caption>
  
  const collectionManager: CollectionManager = new CollectionManager(EnvTypes.STAGING);

  const publicId = 'f1d203eb-cd15-49ff-8852-41846a508bd8'; // unique UUID of the collection

  console.log("Get collection by public ID...");
  const collectionData: CollectionDetailsResponseData = await collectionManager.getCollectionByPublicId(publicId);
  console.log(JSON.stringify(collectionData, null, 2));
   */
  public async getCollectionByPublicId(
    publicId: string
  ): Promise<APIResponseType<CollectionDetailsResponseData> | undefined> {
    if (!publicId) {
      throw new Error("The public ID is required")
    }
    const collectionByPublicId = await this.collectionAPI.getCollectionByPublicId(
      publicId
    );
    return collectionByPublicId;
  }

  /**
   * @summary Get the asset list by collection ID
   * @param {GetAssetByCollectionParams} payload The request params for querying the list of the assets 
   * @returns {CommonPaginateDataTypes<AssetListResponse[]>} The paginated data response (including the list of the assets)
   * @throws {string} Exception: The collectionID is required
   * @throws {string} Exception: The assetType is required
   * @example <caption>Sample of getAssetByCollectionId({}) on Staging env</caption>
  
  const collectionManager: CollectionManager = new CollectionManager(EnvTypes.STAGING);

  const payload: GetAssetByCollectionParams = {
    collectionId: 1,
    assetType: 'NON_SALE',
    limit: 100,
    page: 1
  };

  console.log("Get asset list by collection ID");
  const assetsData: CommonPaginateDataTypes<AssetListResponse[]> = await collectionManager.getAssetByCollectionId(payload);
  console.log(JSON.stringify(assetsData, null, 2));
   */
  public async getAssetByCollectionId(
    payload: GetAssetByCollectionParams
  ): Promise<APIResponseType<CommonPaginateDataTypes<AssetListResponse[]>> | undefined> {
    if (!payload.collectionId) {
      throw new Error('The collectionID is required');
    }
    if (!payload.assetType) {
      throw new Error('The assetType is required');
    }

    const expectedAssetType = payload.assetTypeOutput || 'ASSETS';
    payload.assetTypeOutput = expectedAssetType;

    const listAssetByCollectionId = await this.collectionAPI.getAssetByCollectionId(payload);
    return listAssetByCollectionId;
  }

  /**
   * @description Get total purchased assets group by user
   * @param {GetTotalAssetsByOwnerParams} totalPurchasedAssets  Request for query total assets by owner params
   * @returns {CommonPaginateDataTypes<OwnerAssetsCount[]>} owner assets count result
   * @throws {string} Exception: CollectionId is required
   * @throws {string} Exception: Stark key is required
   * @throws {string} Exception: Internal server error
   * @throws {string} Exception: Get list failed: ${err}
   * @example <caption>Sample of getTotalPurchasedAssetsGroupedByUser({}) on Staging env</caption>
  
  const collectionManager: CollectionManager = new CollectionManager(EnvTypes.STAGING);

  const payload: GetTotalAssetsByOwnerParams = {
    collectionId: 1,
    starkKey: '0xFA....'
  };

  console.log("Get total purchased assets group by users");
  const ownerData: CommonPaginateDataTypes<OwnerAssetsCount[]> = await collectionManager.getTotalPurchasedAssetsGroupedByUser(payload);
  console.log(JSON.stringify(ownerData, null, 2));
   */
  public async getTotalPurchasedAssetsGroupedByUser(
    totalPurchasedAssets: GetTotalAssetsByOwnerParams
  ): Promise<CommonPaginateDataTypes<OwnerAssetsCount[]>> {
    if (!totalPurchasedAssets.collectionId) {
      throw new Error('CollectionId is required');
    }
    if (!totalPurchasedAssets.starkKey) {
      throw new Error ("Stark key is required");
    }

    let response;
    try {
      const result = await this.collectionAPI.getTotalPurchasedAssetsGroupedByUser(totalPurchasedAssets.collectionId,
        totalPurchasedAssets.starkKey, 
        totalPurchasedAssets.paginationType);
      if(result.status === "success") {
        response = result.data;
      } else {
        throw new Error('Fetch ownerlist failed with internal server error');
      }
    } catch (err) {
      throw new Error(`Get ownerlist failed: ${err}`);
    }

    return response;
  }

  /**
   * @description Update collection by contract address and stark key
   * @param {UpdateCollectionByContractAddressParams} payload The updated collection requests params 
   * @returns {CollectionDetailsResponseData} The collection details information
   * @throws {string} Exception: Contract Address is required
   * @throws {string} Exception: Stark key is required
   * @throws {string} Exception: Internal server error
   * @example <caption>Sample of updateCollectionByContractAddress({}) on Staging env</caption>
  
  const collectionManager: CollectionManager = new CollectionManager(EnvTypes.STAGING);

  const payload: UpdateCollectionByContractAddressParams = {
    contractAddress: '0xFC...',
    name: 'New name of the collection',
    starkKey: '0xabc...',
    description: 'New description of collection',
    collectionImageUrl: 'https://collection-banner-url.com'
    iconUrl: 'https://icon-avatar-collection.com'
  };

  console.log("Update collection by smart contract address");
  const collectionData: CollectionDetailsResponseData = await collectionManager.updateCollectionByContractAddress(payload);
  console.log(JSON.stringify(collectionData, null, 2));
   */
  public async updateCollectionByContractAddress(
    payload: UpdateCollectionByContractAddressParams
  ): Promise<CollectionDetailsResponseData> {
    if (!payload.contractAddress) {
      throw new Error("Contract Address is required");
    }

    if (!payload.starkKey) {
      throw new Error("StarkKey is required");
    }

    let updateResult;

    try {
      const response = await this.collectionAPI.updateCollectionByContractAddress(payload);
      if (response?.status === "success") {
        updateResult = response?.data;
      } else {
        throw new Error("Update collection failed with internal server error");
      }
    } catch (err) {
      throw new Error(err);
    }

    return updateResult;
  }

    /**
   * @description Update collection by contract address and partner api key
   * @param {UpdateCollectionByCollectionIdAndApiKeyParams} payload The updated collection requests params 
   * @returns {CollectionDetailsResponseData} The collection details information
   * @throws {string} Exception: Contract Address is required
   * @throws {string} Exception: Stark key is required
   * @throws {string} Exception: Myria account ID is required
   * @example <caption>Sample of updateCollectionByCollectionIdAndApiKey({}) on Staging env</caption>
  
  const collectionManager: CollectionManager = new CollectionManager(EnvTypes.STAGING);

  const payload: UpdateCollectionByCollectionIdAndApiKeyParams = {
    collectionId: '1', // Number string
    name: 'New name of the collection',
    accountId: '0xabc...',
    apiKey: '0x1acd...', // Partner API key
    description: 'New description of collection',
    collectionImageUrl: 'https://collection-banner-url.com'
    iconUrl: 'https://icon-avatar-collection.com'
  };

  console.log("Update collection by smart contract address");
  const collectionData: CollectionDetailsResponseData = await collectionManager.updateCollectionByCollectionIdAndApiKey(payload);
  console.log(JSON.stringify(collectionData, null, 2));
   */
  public async updateCollectionByCollectionIdAndApiKey(
    payload: UpdateCollectionByCollectionIdAndApiKeyParams
  ): Promise<CollectionDetailsResponseData> {
    if (!payload.collectionId) {
      throw new Error("Contract ID is required");
    }

    if (!payload.accountId) {
      throw new Error("Myria account ID is required");
    }

    if (!payload.apiKey) {
      throw new Error("Partner Api Key is required");
    }

    let updateResult;

    try {
      const response = await this.collectionAPI.updateCollectionByCollectionIdAndApiKey(payload);
      if (response?.status === "success") {
        updateResult = response?.data;
      } else {
        throw new Error("Update collection failed with internal server error");
      }
    } catch (err) {
      throw new Error(err);
    }

    return updateResult;
  }



  public async getAttributesByCollectionId(
    id: number
  ): Promise<APIResponseType<AttributesResponse> | undefined> {
    const attributesResponse = await this.collectionAPI.getAttributesByCollectionId(id);
    return attributesResponse;
  }

  /**
   * @summary Create the collection by using myria user ID and api key
   * @param {CreateCollectionByApiKeyParams} payload create Collection request params (name,collectionImageUrl?,description?,iconUrl?,contractAddress,ownerPublicKey,metadataApiUrl,projectId,accountId,apiKey)
   * @throws {string} Exception: Collection name is required
   * @throws {string} Exception: Contract address is required
   * @throws {string} Exception: Owner PublicKey is required
   * @throws {string} Exception: metadataApiUrl is required
   * @throws {string} Exception: Project ID is required
   * @throws {string} Exception: ApiKey is required
   * @throws {string} Exception: Myria User ID is required
   * @throws {string} Exception: Create project failed with internal server error
   * @returns {CreateCollectionResponse | undefined} Collection information data
   * @example <caption>Sample of createCollectionByApiKey() on testnet environment</caption>
   * 
    const collectionManager: CollectionManager = new CollectionManager(EnvTypes.STAGING);

    const params: CreateCollectionByApiKeyParams = {
      name: name_Collection;
      collectionImageUrl?: 'abc.png';
      description?: description;
      iconUrl?: abc.png;
      contractAddress: contractAddress;
      ownerPublicKey: Owner PublicKey;
      metadataApiUrl: metaDataApiURL;
      projectId: 1;
      accountId: accountId;
      apiKey: APIKey
    };

    console.log("Create the Collection...");
    const newCollectionResponse: CreateCollectionResponse = await collectionManager.createCollectionByApiKey(params);

    console.log("Created Collection response:");
    console.log(JSON.stringify(newCollectionResponse, null, 2));
   */

    public async createCollectionByApiKey(payload: CreateCollectionByApiKeyParams): Promise<CreateCollectionResponse> {
      if (!payload.apiKey) {
        throw new Error("API Key is required");
      }
  
      if (!payload.accountId) {
        throw new Error("Account ID is required");
      }
  
      if (!payload.name) {
        throw new Error("Collection Name is required")
      }
  
      if (!payload.contractAddress) {
        throw new Error("Contract Address is required")
      }
  
      if (!payload.projectId) {
        throw new Error("Project Id is required");
      } 

      if (!payload.ownerPublicKey) {
        throw new Error("Owner Public Key is required");
      } 
  
      let collectionCreateRes: CreateCollectionResponse;
  
      try {
        const result = await this.collectionAPI.createCollectionByMyriaUserIdAndApiKey(payload);
        if(result.status === 'success') {
          collectionCreateRes = result.data;
        } else {
          throw new Error('Create Collection failed with internal server error');
        }
      } catch (err) {
        throw new Error(`Create Collection failed with ${err}`);
      }
  
      return collectionCreateRes;
    }

    /**
   * @description Validate the metadata with metadataSchema and metaData URL test
   * @param {ValidateMetadataParams} payload The updated collection requests params 
   * @returns {ValidateMetadataResponse} The collection details information
   * @throws {string} Exception: Metadata Schema is required
   * @throws {string} Exception: Asset Metadata Url is required
   * @throws {string} Http Status Code 500: Validate metadata failed with internal server error
   * @example <caption>Sample of validateMetadata({}) on Staging env</caption>
  
    const collectionManager: CollectionManager = new CollectionManager(EnvTypes.STAGING);

    const payload: ValidateMetadataParams = {
      metadata: [
        {
            "name": "type",
            "type": "string",
            "filterable": true
        },
        {
            "name": "rarity",
            "type": "string",
            "filterable": true
        }
      ],
      "assetMetadataUri": "https://myria.com/v1/sigil/metadata/1"
    };

    console.log("Validate Metadata by metadata url and metadataSchema");
    const validateMetadataRespond: CollectionDetailsResponseData = await collectionManager.validateMetadata(payload);
    console.log(JSON.stringify(validateMetadataRespond, null, 2));
      */
    public async validateMetadata(
      payload: ValidateMetadataParams
    ): Promise<ValidateMetadataResponse> {
      if (!payload.metadata.length) {
        throw new Error("Metadata Schema is required");
      }

      if (!payload.assetMetadataUri) {
        throw new Error("Asset Metadata Uri is required");
      }

      let resultValidateMetadata;

      try {
        const response =
          await this.collectionAPI.validateMetadataSchemaWithTestMetadataUrl(
            payload
          );
        if (response?.status === "success") {
          resultValidateMetadata = response?.data;
        } else {
          throw new Error("Validate metadata failed with internal server error");
        }
      } catch (err) {
        throw new Error(err);
      }

      return resultValidateMetadata;
    }


  validationParams(params: any): any {
    for (const keys of params) {
      if (!params[keys]) {
        throw new Error(`Invalid ${keys}`);
      }
    }
    return true;
  }
}