import { MintMarketpAPI } from "../core/apis/mint.marketp.api";
import {
GetMintedTransactionResponse,
MintERC20Params,
MintERC20Response,
MintERC721Params,
MintERC721Response,
GetMintedAssetsResponse,
GetMintedAssetsParams,
BulkMintERC721Params,
BulkMintERC721ResponseData,
FeeType,
FeeData,
BulkMintQueueAsyncParams,
BulkMintQueueAsyncResponseData,
BulkMintQueueAsyncParamsAPI,
BulkMintQueueParams,
QueryMintingParams,
QueryMintingResponse
} from "../types";
import { EnvTypes } from "../typesBundle";
/**
* Create MintingManager module
* @class MintingManager
* @param {EnvTypes} env Environment type (DEV / STAGING / PREPROD / PROD)
* @example <caption>MintingManager instantiation</caption>
const mintingManager = new MintingManager(EnvTypes.STAGING);
*
*/
export class MintingManager {
private mintMarketpAPI: MintMarketpAPI;
constructor(env: EnvTypes) {
this.mintMarketpAPI = new MintMarketpAPI(env);
}
private async createMintTransactionERC20(
data: MintERC20Params
): Promise<MintERC20Response | undefined>{
let mintTransactionERC20: any;
try {
if (this.validationParams(Object.keys(data), data)) {
const result = await this.mintMarketpAPI.createMintTransactionERC20(data);
if (result?.status === "success") {
mintTransactionERC20 = result.data;
}
}
} catch (error) {
return error;
}
return mintTransactionERC20;
}
/**
* @summary Create a single NFT (MINTABLE_ERC721) through mint transaction in Myria system
* @param {MintERC721Params} data Request params for minting ERC721
* @returns {MintERC721Response | undefined} Mint response data for ERC721 (including assets / transactionInformation...)
* @example <caption>Sample function for createMintTransactionERC721({})</caption>
*
const mintingManager: MintingManager = new MintingManager(env);
const starkKey = '0xabc....'; // Your registered stark key with Myria system
const contractAddress = '0xdf...'; // Unique smart contract address for collection
const metadataApiUrl = 'https://metadata-example.com'; // Sample of base metadata url
const tokenId = 1; // Your unique token ID to identify and locate the NFT asset in the storage
const percentage = 10; // 10% fee for purchase transaction to return to creator
const royaltyRecipient = '0xpad....'; // Sample wallet address of receiver (author/creator of the NFT)
const params: MintERC721Params = {
starkKey: starkKey,
contractAddress: contractAddress,
uri: `${metadataApiUrl}/${tokenId}`,
tokenId: String(tokenId),
description: "mry asset",
fees: [
{
percentage: feePercentage,
receiptAddress: royaltyRecipient,
feeType: FeeType.ROYALTY
},
],
};
const mintTransactionResponse = await mintingManager.createMintTransactionERC721(
params
);
*/
public async createMintTransactionERC721(
data: MintERC721Params
): Promise<MintERC721Response | undefined> {
let mintTransactionERC721: any;
try {
if (this.validationParams(Object.keys(data), data)) {
const feeData = this.getDefaultFeeData(data.fees);
const dataWithFees = {...data};
dataWithFees.fees = feeData;
const result = await this.mintMarketpAPI.createMintTransactionERC721(dataWithFees);
if (result?.status === "success") {
mintTransactionERC721 = result.data;
}
}
} catch (error) {
return error;
}
return mintTransactionERC721;
}
public getDefaultFeeData(feesData: FeeData[]): FeeData[] {
return feesData.map((item: FeeData) => {
if (!item.feeType) {
return {
...item,
feeType: FeeType.ROYALTY
}
}
return item;
});
}
/**
* @summary Get transaction details for minting
* @param {number} transactionId Unique sequence ID of transaction
* @returns {GetMintedTransactionResponse} Details information of minted transaction
* @throws {string} Exception: TransactionId is required
* @throws {string} Exception: Get minted transaction details failure with error: ${serverError}
*/
public async getMintTransactionDetails(
transactionId: number
): Promise<GetMintedTransactionResponse> {
if (!transactionId) {
throw new Error("TransactionId is required");
}
let result;
try {
result = await this.mintMarketpAPI.requestGetMintTransaction(transactionId);
} catch (error) {
throw new Error(`Get minted transaction details failure with error: [${error}]`);
}
return result;
}
public async getMintedAssetByStarkKey(
data: GetMintedAssetsParams
): Promise<GetMintedAssetsResponse> {
const result = await this.mintMarketpAPI.requestGetMintStarkKey(data);
try {
if (!data.starkKey) {
throw new Error("StarkKey is required");
} else
return result;
}
catch (error) { return error; }
}
/**
* @summary Processes the bulk mint for list of assets (MINTABLE_ERC721)
* @param {BulkMintERC721Params} payload Request for bulk mint list of ERC721
* @returns {BulkMintERC721ResponseData} Bulk mint response data
* @throws {string} Exception: Stark Key is required
* @throws {string} Exception: Contract address is required
* @throws {string} Exception: Assets length should be greater than 0
* @throws {string} Exception: (x) th asset's uri is required
* @throws {string} Exception: (x) th asset's tokenId is required
* @throws {string} Http Status 500: Bulk mint failed with internal server error
* @example <caption>Sample function for bulkMintNfts({})</caption>
const mintingManager: MintingManager = new MintingManager(env);
const feePercentage = 2;
const startTokenId = 1;
const endTokenId = 30;
const starkKey: string = config.stark_key;
const contractAddress: string = config.collection_contract_address;
const metadataApiUrl: string = config.metadata_api_url;
const royaltyRecipient: string = config.public_key;
let assetsToMint = [];
console.log("Preparing assets to mint...");
for (let i = startTokenId; i <= endTokenId; i++) {
const asset: MintAssetErc721Info = {
uri: `${metadataApiUrl}/${i}`,
tokenId: String(i),
description: 'mry asset',
fees: [{
percentage: feePercentage,
receiptAddress: royaltyRecipient,
feeType: FeeType.ROYALTY
}]
};
assetsToMint.push(asset);
}
console.log(assetsToMint);
const params: BulkMintERC721Params = {
starkKey: starkKey,
contractAddress: contractAddress,
assets: assetsToMint,
isSupportGetBulkMetadata: true,
fees: [{
percentage: feePercentage,
receiptAddress: royaltyRecipient,
feeType: FeeType.ROYALTY
}]
};
console.log("Initiating a bulk minting...");
const mintResult: BulkMintERC721ResponseData = await mintingManager.bulkMintNfts(params);
console.log("Bulk minting is completed. Result: ", mintResult);
*/
public async bulkMintNfts(
payload: BulkMintERC721Params
): Promise<BulkMintERC721ResponseData> {
if (!payload.starkKey) {
throw new Error("Stark Key is required");
}
if (!payload.contractAddress) {
throw new Error("Contract address is required");
}
if (payload.assets.length === 0) {
throw new Error("Assets length should be greater than 0");
}
payload.assets.forEach((asset: any, index: number) => {
if (!asset.uri) {
throw new Error(`${index + 1}th asset's uri is required`);
}
if (!asset.tokenId) {
throw new Error(`${index + 1}th asset's tokenId is required`);
}
});
let bulkMintResponse: BulkMintERC721ResponseData;
const feeData = payload.fees ? this.getDefaultFeeData(payload.fees): [];
const dataWithFees = {...payload};
dataWithFees.fees = feeData;
try {
const response = await this.mintMarketpAPI.bulkMintERC721(dataWithFees);
if (response.status === "success") {
bulkMintResponse = response.data;
} else {
throw new Error("Bulk mint failed with internal server error");
}
} catch (err) {
return err
}
return bulkMintResponse;
}
/**
* @summary Processes the bulk mint in queue for list of NFTs asynchronously (MINTABLE_ERC721)
* @param {BulkMintQueueParams} payload Request params for bulk mint queue
* @returns {BulkMintERC721ResponseData} Bulk mint queue response data
* @throws {string} Exception: apiKey is required
* @throws {string} Exception: RequestId is required
* @throws {string} Exception: PartnerRefId is required
* @throws {string} Exception: GroupRequestId is required
* @throws {string} Exception: RequestDescription is required
* @throws {string} Exception: AccountId is required
* @throws {string} Exception: CollectionId is required
* @throws {string} Exception: Assets length should be greater than 0
* @throws {string} Exception: (x) th asset's tokenId is required
* @throws {string} Exception: (x) th asset's description is required
* @throws {string} Exception: (x) th asset's trackingId is required
* @throws {string} Exception: (x) th asset's mintForStarkKey invalid
* @throws {string} Http Status 500: Bulk mint failed with internal server error
* @example <caption>Sample function for bulkMintNftsV2({})</caption>
const mintingManager: MintingManager = new MintingManager(env);
const feePercentage = 2;
const startTokenId = 1;
const endTokenId = 30;
const requestId: string = config.requestId;
const partnerRefId: string = config.partnerRefId;
const groupRequestId: string = config.groupRequestId;
const requestDescription: string = config.requestDescription;
const accountId: string = config.accountId;
const apiKey: string = config.apiKey;
const collectionId: string = config.collectionId;
const isSupportGetBulkMetadata: boolean = config.isSupportGetBulkMetadata;
const royaltyRecipient: string = config.royaltyRecipient;
let assetsToMintAsync: MintAssetErc721InfoAsync[] = [];
console.log("Preparing assets to mint...");
for (let i = startTokenId; i <= endTokenId; i++) {
const asset: MintAssetErc721InfoAsync = {
tokenId: String(i),
description: 'mry asset',
fees: [{
percentage: feePercentage,
receiptAddress: royaltyRecipient,
feeType: FeeType.ROYALTY
}],
mintForStarkKey: '0x.....',
trackingId: 'trackingID',
};
assetsToMintAsync.push(asset);
}
console.log(assetsToMintAsync);
const params: BulkMintQueueParams = {
apiKey,
requestId,
partnerRefId,
groupRequestId,
requestDescription,
accountId,
collectionId,
assets: assetsToMintAsync,
isSupportGetBulkMetadata,
fees: [{
percentage: feePercentage,
receiptAddress: royaltyRecipient,
feeType: FeeType.ROYALTY
}]
};
console.log("Initiating a bulk minting...");
const mintV2Result: BulkMintERC721ResponseData = await mintingManager.bulkMintNftsV2(params);
console.log("Bulk minting is completed. Result: ", mintResult);
*/
public async bulkMintNftsV2(
payload: BulkMintQueueParams
): Promise<BulkMintERC721ResponseData> {
if (!payload.apiKey) {
throw new Error("Api key is required");
}
if (!payload.requestId) {
throw new Error("RequestId is required");
}
if (!payload.partnerRefId) {
throw new Error("PartnerRefId is required");
}
if (!payload.groupRequestId) {
throw new Error("GroupRequestId is required");
}
if (!payload.requestDescription) {
throw new Error("RequestDescription is required");
}
if (!payload.accountId) {
throw new Error("AccountId is required");
}
if (!payload.collectionId) {
throw new Error("CollectionId is required");
}
if (!(payload.assets.length > 0)) {
throw new Error("Assets length should be greater than 0");
}
payload.assets.forEach((asset: any, index: number) => {
if (!asset.tokenId) {
throw new Error(`${index + 1}th asset's tokenId is required`);
}
if (!asset.description) {
throw new Error(`${index + 1}th asset's description is required`);
}
if (!asset.trackingId) {
throw new Error(`${index + 1}th asset's trackingId is required`);
}
if (asset.mintForStarkKey) {
if(!asset.mintForStarkKey.includes('0x')) {
throw new Error(`${index + 1}th asset's mintforStarkKey invalid!`);
}
}
});
let bulkMintResponse: BulkMintERC721ResponseData;
const feeData = payload.fees ? this.getDefaultFeeData(payload.fees): [];
const dataWithFees: BulkMintQueueAsyncParamsAPI = {...payload};
dataWithFees.fees = feeData;
try {
const response = await this.mintMarketpAPI.requestBulkMintV2(dataWithFees, payload.apiKey);
if (response.status === "success") {
bulkMintResponse = response.data;
}
else {
throw new Error("Bulk mint failed with internal server error");
}
} catch (err) {
throw new Error(err);
}
return bulkMintResponse;
}
/**
* @summary Processes the bulk mint in queue for list of NFTs asynchronously (MINTABLE_ERC721)
* @param {BulkMintQueueAsyncParams} payload Request params for bulk mint queue
* @returns {BulkMintQueueAsyncResponseData} Bulk mint queue response data
* @throws {string} Exception: apiKey is required
* @throws {string} Exception: RequestId is required
* @throws {string} Exception: PartnerRefId is required
* @throws {string} Exception: GroupRequestId is required
* @throws {string} Exception: RequestDescription is required
* @throws {string} Exception: AccountId is required
* @throws {string} Exception: CollectionId is required
* @throws {string} Exception: Assets length should be greater than 0
* @throws {string} Exception: (x) th asset's tokenId is required
* @throws {string} Exception: (x) th asset's description is required
* @throws {string} Exception: (x) th asset's trackingId is required
* @throws {string} Exception: (x) th asset's mintForStarkKey invalid
* @throws {string} Http Status 500: Bulk mint failed with internal server error
* @example <caption>Sample function for bulkMintNftsQueueAsync({})</caption>
const mintingManager: MintingManager = new MintingManager(env);
const feePercentage = 2;
const startTokenId = 1;
const endTokenId = 30;
const requestId: string = config.requestId;
const partnerRefId: string = config.partnerRefId;
const groupRequestId: string = config.groupRequestId;
const requestDescription: string = config.requestDescription;
const accountId: string = config.accountId;
const apiKey: string = config.apiKey;
const collectionId: string = config.collectionId;
const isSupportGetBulkMetadata: boolean = config.isSupportGetBulkMetadata;
const royaltyRecipient: string = config.royaltyRecipient;
let assetsToMintAsync = [];
console.log("Preparing assets to mint...");
for (let i = startTokenId; i <= endTokenId; i++) {
const asset: MintAssetErc721InfoAsync = {
tokenId: String(i),
description: 'mry asset',
fees: [{
percentage: feePercentage,
receiptAddress: royaltyRecipient,
feeType: FeeType.ROYALTY
}],
mintForStarkKey: '0x.....',
trackingId: 'trackingID',
};
assetsToMintAsync.push(asset);
}
console.log(assetsToMintAsync);
const params: BulkMintQueueAsyncParams = {
apiKey,
requestId,
partnerRefId,
groupRequestId,
requestDescription,
accountId,
collectionId,
assets: assetsToMintAsync,
isSupportGetBulkMetadata,
fees: [{
percentage: feePercentage,
receiptAddress: royaltyRecipient,
feeType: FeeType.ROYALTY
}]
};
console.log("Initiating a bulk minting...");
const mintV2Result: BulkMintQueueAsyncResponseData = await mintingManager.bulkMintNftsQueueAsync(params);
console.log("Bulk minting is completed. Result: ", mintResult);
*/
public async bulkMintNftsQueueAsync(
payload: BulkMintQueueAsyncParams
): Promise<BulkMintQueueAsyncResponseData> {
if (!payload.apiKey) {
throw new Error("Api key is required");
}
if (!payload.requestId) {
throw new Error("RequestId is required");
}
if (!payload.partnerRefId) {
throw new Error("PartnerRefId is required");
}
if (!payload.groupRequestId) {
throw new Error("GroupRequestId is required");
}
if (!payload.requestDescription) {
throw new Error("RequestDescription is required");
}
if (!payload.accountId) {
throw new Error("AccountId is required");
}
if (!payload.collectionId) {
throw new Error("CollectionId is required");
}
if (!(payload.assets.length > 0)) {
throw new Error("Assets length should be greater than 0");
}
payload.assets.forEach((asset: any, index: number) => {
if (!asset.tokenId) {
throw new Error(`${index + 1}th asset's tokenId is required`);
}
if (!asset.description) {
throw new Error(`${index + 1}th asset's description is required`);
}
if (!asset.trackingId) {
throw new Error(`${index + 1}th asset's trackingId is required`);
}
if (asset.mintForStarkKey) {
if(!asset.mintForStarkKey.includes('0x')) {
throw new Error(`${index + 1}th asset's mintforStarkKey invalid!`);
}
}
});
let bulkMintAsyncResponse: BulkMintQueueAsyncResponseData;
const feeData = payload.fees ? this.getDefaultFeeData(payload.fees): [];
const dataWithFees: BulkMintQueueAsyncParamsAPI = {...payload};
dataWithFees.fees = feeData;
try {
const response = await this.mintMarketpAPI.requestBulkMintAsync(dataWithFees, payload.apiKey);
if (response.status === "success") {
bulkMintAsyncResponse = response.data;
} else {
throw new Error("Bulk mint failed with internal server error");
}
} catch (err) {
throw new Error(err);
}
return bulkMintAsyncResponse;
}
/**
* @summary Processes query the list of NFTs which have been minted asynchronously (MINTABLE_ERC721)
* @param {QueryMintingParams} payload Request params for querying the minted assets
* @returns {QueryMintingResponse} Bulk mint queue response data
* @throws {string} Exception: DeveloperApiKey is required
* @throws {string} Exception: Group request ID is required
* @throws {string} Exception: PartnerRefId is required
* @example <caption>Sample function for QueryMintingParams({})</caption>
const mintingManager: MintingManager = new MintingManager(env);
const params: QueryMintingParams = {
partnerRefId: 'Project ID of game which can be retrieved via Developer Portal',
groupRequestId: 'Random group request ID',
developerApiKey: 'Developer API key which can be retrieved via Developer Portal'
}
console.log("Initiating the request query for minting assets...");
const queryMintedAssetResponse: QueryMintingResponse = await mintingManager.queryMintingAssets(params);
console.log("Querying minted result: ", queryMintedAssetResponse);
*/
public async queryMintingAssets(params: QueryMintingParams): Promise<QueryMintingResponse> {
if (!params.developerApiKey) {
throw new Error('Developer API Key is required');
}
if (!params.groupRequestId) {
throw new Error('Group request ID is required');
}
if (!params.partnerRefId) {
throw new Error('Partner reference ID is required');
}
try {
const mintingResponse = await this.mintMarketpAPI.queryMintingAssets(params);
if (mintingResponse.status === 'success') {
return mintingResponse.data;
}
throw new Error('There is internal server error, please check again with response error');
} catch (err) {
throw new Error(err);
}
}
// TODO to be refactor using schema validation
validationParams(params: string[], data: any): boolean {
for (const key of params) {
if (key === "description") {
continue;
}
if (!data[key]) {
throw new Error(`${key} is required`);
}
}
return true;
}
}
Source