updates
This commit is contained in:
@@ -39,7 +39,7 @@ Parse.Cloud.define('getBankBalance', async (request) => {
|
||||
const record = await query.first({ useMasterKey: true });
|
||||
// console.log('record', record.get('kash'));
|
||||
if (!record) {
|
||||
log.warning(`No bank records found for user: ${params.userId}`);
|
||||
// No bank records is normal for new users - return default values without logging
|
||||
return {
|
||||
success: true,
|
||||
data: {
|
||||
|
||||
@@ -2,6 +2,9 @@ const { createCanvas, loadImage } = require('canvas');
|
||||
const fs = require('fs').promises;
|
||||
const path = require('path');
|
||||
|
||||
// Import the correct function name from checkOwnership.js
|
||||
const { batchVerifyOwnership } = require('../../../utility/web3/chia/checkOwnership');
|
||||
|
||||
// Logging utilities
|
||||
const log = {
|
||||
section: (title) => console.log(`\n🔸 ${'-'.repeat(20)} ${title} ${'-'.repeat(20)}`),
|
||||
@@ -333,6 +336,93 @@ Parse.Cloud.define("breedAssetsById", async (request) => {
|
||||
throw new Error('Could not find one or both parent Dracattus. Check dracattus1 and dracattus2 parameters.');
|
||||
}
|
||||
|
||||
log.success('Both parent Dracattus found successfully');
|
||||
|
||||
// Check for ownership using encoded_ids - Only if wallet was provided
|
||||
if (wallet) {
|
||||
log.section('Ownership Verification');
|
||||
log.debug(`Starting ownership verification for wallet: ${wallet}`);
|
||||
|
||||
// First check if godMode is enabled - if it is, skip ownership checks
|
||||
let godMode = false;
|
||||
try {
|
||||
const config = await Parse.Config.get({ useMasterKey: true });
|
||||
godMode = config.get('godMode') === true;
|
||||
|
||||
log.debug(`Parse Config loaded successfully, godMode value: ${godMode}`);
|
||||
|
||||
if (godMode) {
|
||||
log.success('GOD MODE enabled - bypassing ownership verification');
|
||||
} else {
|
||||
log.info('GOD MODE not enabled - verifying ownership');
|
||||
}
|
||||
} catch (error) {
|
||||
log.error(`Error checking godMode config: ${error.message}`);
|
||||
log.debug(`Config error details: ${JSON.stringify(error)}`);
|
||||
}
|
||||
|
||||
// If not in godMode, proceed with ownership check
|
||||
if (!godMode) {
|
||||
try {
|
||||
// Get encoded_ids from both Dracattus
|
||||
const encoded_id1 = parent1.get('encoded_id');
|
||||
const encoded_id2 = parent2.get('encoded_id');
|
||||
|
||||
log.debug(`Retrieved encoded_ids: [${encoded_id1}, ${encoded_id2}]`);
|
||||
|
||||
// Check if encoded_ids exist before proceeding
|
||||
if (!encoded_id1 || !encoded_id2) {
|
||||
log.error('One or both Dracattus are missing encoded_id (launcher_bech32)');
|
||||
|
||||
// Display which encoded_ids are missing for better debugging
|
||||
const missingIdsInfo = {
|
||||
'Dracattus 1': {
|
||||
id: parent1.id,
|
||||
name: parent1.get('name'),
|
||||
encoded_id: encoded_id1 || 'MISSING'
|
||||
},
|
||||
'Dracattus 2': {
|
||||
id: parent2.id,
|
||||
name: parent2.get('name'),
|
||||
encoded_id: encoded_id2 || 'MISSING'
|
||||
}
|
||||
};
|
||||
|
||||
console.table(missingIdsInfo);
|
||||
|
||||
throw new Error('Cannot verify ownership: One or both Dracattus are missing encoded_id (launcher_bech32)');
|
||||
}
|
||||
|
||||
log.info(`Verifying ownership of Dracattus NFTs (${encoded_id1}, ${encoded_id2}) by wallet ${wallet}`);
|
||||
log.debug(`Calling batchVerifyOwnership with wallet=${wallet} and encoded_ids=[${encoded_id1}, ${encoded_id2}]`);
|
||||
|
||||
// Call the batchVerifyOwnership function to check both NFTs at once
|
||||
const { allOwned, results } = await batchVerifyOwnership(wallet, [encoded_id1, encoded_id2]);
|
||||
|
||||
log.debug(`Verification results received: ${JSON.stringify({ allOwned, results })}`);
|
||||
|
||||
// Display results in a table
|
||||
console.table({
|
||||
[encoded_id1]: results[encoded_id1] ? 'Owned ✓' : 'Not Owned ✗',
|
||||
[encoded_id2]: results[encoded_id2] ? 'Owned ✓' : 'Not Owned ✗'
|
||||
});
|
||||
|
||||
if (!allOwned) {
|
||||
log.error('Ownership verification failed - user does not own both NFTs');
|
||||
throw new Error('You do not own both of these Dracattus NFTs');
|
||||
}
|
||||
|
||||
log.success('Ownership verification passed - proceeding with breeding');
|
||||
} catch (verificationError) {
|
||||
log.error(`Ownership verification failed: ${verificationError.message}`);
|
||||
log.debug(`Error stack: ${verificationError.stack}`);
|
||||
throw new Error(`Ownership verification error: ${verificationError.message}`);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log.warning('No wallet address provided - skipping ownership verification');
|
||||
}
|
||||
|
||||
// Check if either parent has reached their monthly breeding limit
|
||||
const parent1MintBalance = parent1.get('mintBalance') ?? 0;
|
||||
const parent2MintBalance = parent2.get('mintBalance') ?? 0;
|
||||
|
||||
132
cloud/dracattus/api/collection/getDracattusByNftId.js
Normal file
132
cloud/dracattus/api/collection/getDracattusByNftId.js
Normal file
@@ -0,0 +1,132 @@
|
||||
Parse.Cloud.define("getDracattusByNftId", async (request) => {
|
||||
try {
|
||||
const { nft_id } = request.params;
|
||||
|
||||
// Validate input exists
|
||||
if (!nft_id) {
|
||||
throw new Error("Missing required parameter: nft_id");
|
||||
}
|
||||
|
||||
// Validate nft_id is a non-empty string
|
||||
if (typeof nft_id !== 'string' || nft_id.trim() === '') {
|
||||
throw new Error("nft_id must be a non-empty string");
|
||||
}
|
||||
|
||||
// Validate nft_id format (64-character hex string)
|
||||
const nftIdPattern = /^[a-f0-9]{64}$/i;
|
||||
if (!nftIdPattern.test(nft_id)) {
|
||||
throw new Error("nft_id must be a 64-character hex string");
|
||||
}
|
||||
|
||||
// Create query for DRACATTUS class
|
||||
const query = new Parse.Query("DRACATTUS");
|
||||
|
||||
// Add constraint for the nft_id field
|
||||
query.equalTo("nft_id", nft_id);
|
||||
|
||||
// Include all fields we might need
|
||||
query.select([
|
||||
"name",
|
||||
"encoded_id",
|
||||
"nft_id",
|
||||
"taxonomy",
|
||||
"edition",
|
||||
"syncscore",
|
||||
"prowess",
|
||||
"location",
|
||||
"background",
|
||||
"base",
|
||||
"wings",
|
||||
"belly",
|
||||
"fur",
|
||||
"ears",
|
||||
"eyes",
|
||||
"horns",
|
||||
"mouth",
|
||||
"tail_tip",
|
||||
"attributes",
|
||||
"chain",
|
||||
"thumbnail_uri",
|
||||
"is_owned",
|
||||
"health",
|
||||
"attack",
|
||||
"defense",
|
||||
"parent1",
|
||||
"parent2",
|
||||
]);
|
||||
|
||||
// Execute query
|
||||
const results = await query.find({ useMasterKey: true });
|
||||
|
||||
// Check if any results were found
|
||||
if (results.length === 0) {
|
||||
return {
|
||||
success: false,
|
||||
error: "No DRACATTUS record found for the provided nft_id",
|
||||
queried_nft_id: nft_id
|
||||
};
|
||||
}
|
||||
|
||||
// For nft_id, we expect only one result since it should be unique
|
||||
const record = results[0];
|
||||
const thumbnailUri = record.get("thumbnail_uri");
|
||||
|
||||
const formattedResult = {
|
||||
objectId: record.id,
|
||||
name: record.get("name"),
|
||||
thumbnail_uri: thumbnailUri ? (thumbnailUri._url || thumbnailUri.url || thumbnailUri) : null,
|
||||
encoded_id: record.get("encoded_id"),
|
||||
nft_id: record.get("nft_id"),
|
||||
taxonomy: record.get("taxonomy"),
|
||||
edition: record.get("edition"),
|
||||
syncscore: record.get("syncopate"),
|
||||
prowess: record.get("prowess"),
|
||||
location: record.get("location"),
|
||||
background: record.get("background"),
|
||||
base: record.get("base"),
|
||||
wings: record.get("wings"),
|
||||
belly: record.get("belly"),
|
||||
fur: record.get("fur"),
|
||||
ears: record.get("ears"),
|
||||
eyes: record.get("eyes"),
|
||||
horns: record.get("horns"),
|
||||
mouth: record.get("mouth"),
|
||||
tail_tip: record.get("tail_tip"),
|
||||
attributes: record.get("attributes"),
|
||||
chain: record.get("chain"),
|
||||
createdAt: record.createdAt,
|
||||
updatedAt: record.updatedAt,
|
||||
// Add metadata structure for compatibility with view-asset page
|
||||
metadata: {
|
||||
attributes: record.get("attributes"),
|
||||
details: {
|
||||
background: record.get("background"),
|
||||
base: record.get("base"),
|
||||
wings: record.get("wings"),
|
||||
belly: record.get("belly"),
|
||||
fur: record.get("fur"),
|
||||
ears: record.get("ears"),
|
||||
eyes: record.get("eyes"),
|
||||
horns: record.get("horns"),
|
||||
mouth: record.get("mouth"),
|
||||
tail_tip: record.get("tail_tip"),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
success: true,
|
||||
results: [formattedResult],
|
||||
total: 1,
|
||||
queried_nft_id: nft_id
|
||||
};
|
||||
|
||||
} catch (error) {
|
||||
console.error("Error in getDracattusByNftId:", error);
|
||||
return {
|
||||
success: false,
|
||||
error: error.message,
|
||||
queried_nft_id: nft_id
|
||||
};
|
||||
}
|
||||
});
|
||||
@@ -14,6 +14,107 @@ const generateSHA256Hash = async (url) => {
|
||||
}
|
||||
};
|
||||
|
||||
// Helper function to create split royalty address using splitxch API
|
||||
const createSplitRoyaltyAddress = async (originalAddress, targetAddress, minterPoints) => {
|
||||
try {
|
||||
const originalPoints = 9850 - minterPoints; // Total available minus minter share
|
||||
|
||||
const payload = {
|
||||
recipients: [
|
||||
{
|
||||
name: "original",
|
||||
address: originalAddress,
|
||||
points: originalPoints,
|
||||
id: 1
|
||||
},
|
||||
{
|
||||
name: "minter",
|
||||
address: targetAddress,
|
||||
points: minterPoints,
|
||||
id: 2
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
console.log(` 🔧 Payload Details:`);
|
||||
console.log(` 📍 Original Wallet: ${originalAddress}`);
|
||||
console.log(` 📍 Minter Wallet: ${targetAddress}`);
|
||||
console.log(` 📊 Original Points: ${originalPoints.toLocaleString()}`);
|
||||
console.log(` 📊 Minter Points: ${minterPoints.toLocaleString()}`);
|
||||
console.log(` 🌐 Sending request to SplitXCH API...`);
|
||||
|
||||
const response = await fetch('https://splitxch.com/api/compute/fast', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
console.log(` ❌ SplitXCH API Error (${response.status}): ${errorText}`);
|
||||
throw new Error(`SplitXCH API error (${response.status}): ${errorText}`);
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (result.address) {
|
||||
console.log(` 🎊 SplitXCH API Response Success!`);
|
||||
console.log(` 🏦 Split Address: ${result.address}`);
|
||||
console.log(` 🆔 Split ID: ${result.id}`);
|
||||
console.log(` 📈 Progress: ${result.pctProgress || 'N/A'}%`);
|
||||
return {
|
||||
address: result.address,
|
||||
splitId: result.id,
|
||||
originalPoints,
|
||||
minterPoints
|
||||
};
|
||||
} else {
|
||||
console.log(` ❌ Invalid SplitXCH Response: ${JSON.stringify(result)}`);
|
||||
throw new Error(`SplitXCH API did not return an address: ${JSON.stringify(result)}`);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.log(` ⚠️ SPLITXCH ERROR DETAILS:`);
|
||||
console.error(` 🚨 Error Type: ${error.name || 'Unknown'}`);
|
||||
console.error(` 💬 Message: ${error.message}`);
|
||||
if (error.stack) {
|
||||
console.error(` 📋 Stack: ${error.stack.split('\n')[0]}`);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
// Helper function to calculate minter's royalty share based on magic field
|
||||
const calculateMinterRoyaltyShare = (magicValue) => {
|
||||
// Ensure magic value is within valid range
|
||||
const clampedMagic = Math.max(0, Math.min(100, magicValue || 0));
|
||||
|
||||
console.log(` 🧮 CALCULATION BREAKDOWN:`);
|
||||
console.log(` 🔢 Raw Magic Value: ${magicValue}`);
|
||||
console.log(` ⚖️ Clamped Magic: ${clampedMagic} (0-100 range)`);
|
||||
console.log(` 🏆 Available Points: 9,850 (10,000 - 150 platform fee)`);
|
||||
console.log(` 📐 Formula: Magic × 49.25 = Minter Points`);
|
||||
|
||||
// Calculate minter's share as percentage of available points (max 50%)
|
||||
// Available points: 9850 (10000 - 150 platform fee)
|
||||
// Minter gets: (magic / 100) * 50% of available points
|
||||
const minterPoints = Math.round(clampedMagic * 49.25); // 49.25 = 9850 * 0.5 / 100
|
||||
|
||||
const result = {
|
||||
minterPoints,
|
||||
minterPercentage: (minterPoints / 9850) * 100,
|
||||
originalPoints: 9850 - minterPoints,
|
||||
originalPercentage: ((9850 - minterPoints) / 9850) * 100
|
||||
};
|
||||
|
||||
console.log(` ✨ ${clampedMagic} × 49.25 = ${minterPoints} minter points`);
|
||||
console.log(` 🏛️ 9,850 - ${minterPoints} = ${result.originalPoints} original points`);
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
Parse.Cloud.define('mintAsset', async (request) => {
|
||||
try {
|
||||
const { objectId, targetWallet, requested_mojos, isMainnet = true } = request.params;
|
||||
@@ -23,7 +124,7 @@ Parse.Cloud.define('mintAsset', async (request) => {
|
||||
|
||||
// Get config variables and choose mainnet vs testnet based on isMainnet parameter
|
||||
const config = await Parse.Config.get({ useMasterKey: true });
|
||||
const royaltyAddress = config.get('DRAC_MINTGARDEN_ROYALY_ADDRESS');
|
||||
const originalRoyaltyAddress = config.get('DRAC_MINTGARDEN_ROYALY_ADDRESS');
|
||||
|
||||
// Use environment variable pattern matching server.js configuration
|
||||
const serverUrl = process.env.NODE_ENV === 'dev' ? process.env.serverURL : process.env.serverURLProd;
|
||||
@@ -45,7 +146,7 @@ Parse.Cloud.define('mintAsset', async (request) => {
|
||||
console.log(`Minting on ${isMainnet ? 'MAINNET' : 'TESTNET'} using ${mintgardenApiUrl}`);
|
||||
|
||||
// Get target address from either targetWallet param or config variable
|
||||
const targetAddress = targetWallet || royaltyAddress;
|
||||
const targetAddress = targetWallet || originalRoyaltyAddress;
|
||||
if (!targetAddress) {
|
||||
throw new Error('No target address available. Please provide targetWallet or set DRAC_MINTGARDEN_ROYALY_ADDRESS in Parse Config');
|
||||
}
|
||||
@@ -165,6 +266,84 @@ Parse.Cloud.define('mintAsset', async (request) => {
|
||||
.update(JSON.stringify(metadataJson))
|
||||
.digest('hex');
|
||||
|
||||
// Determine royalty address (split or original)
|
||||
let finalRoyaltyAddress = originalRoyaltyAddress;
|
||||
let splitRoyaltyInfo = null;
|
||||
let royaltyCalculationResults = null; // Store calculation results for return data
|
||||
const royaltyPercentage = 33; // Keep at 33% as requested
|
||||
|
||||
// Check if we should use split royalties
|
||||
if (targetWallet && targetWallet !== originalRoyaltyAddress && object.className === 'DRACATTUS') {
|
||||
console.log('\n💎 ═══════════════════════════════════════════════════════════════════════════════════════ 💎');
|
||||
console.log('💎 🔮 SPLIT ROYALTY ANALYSIS 🔮 💎');
|
||||
console.log('💎 ═══════════════════════════════════════════════════════════════════════════════════════ 💎');
|
||||
|
||||
try {
|
||||
const magicValue = object.get('magic') || 0;
|
||||
console.log(`\n🧙♂️ MAGIC DISCOVERY:`);
|
||||
console.log(` ✨ Dracattus Magic Level: ${magicValue}/100`);
|
||||
console.log(` 🆔 DRACATTUS ID: ${objectId}`);
|
||||
|
||||
const royaltyShare = calculateMinterRoyaltyShare(magicValue);
|
||||
|
||||
// Store results for return data (avoid duplicate calculation)
|
||||
royaltyCalculationResults = {
|
||||
magicValue: magicValue,
|
||||
magicValueClamped: Math.max(0, Math.min(100, magicValue || 0)),
|
||||
minterSharePercentage: royaltyShare.minterPercentage,
|
||||
originalSharePercentage: royaltyShare.originalPercentage,
|
||||
minterPoints: royaltyShare.minterPoints,
|
||||
originalPoints: royaltyShare.originalPoints,
|
||||
totalAvailablePoints: 9850,
|
||||
platformFeePoints: 150,
|
||||
minterWallet: targetWallet,
|
||||
originalWallet: originalRoyaltyAddress
|
||||
};
|
||||
|
||||
console.log(`\n📊 ROYALTY CALCULATION RESULTS:`);
|
||||
console.log(` 🎯 Minter Share: ${royaltyShare.minterPercentage.toFixed(2)}% (${royaltyShare.minterPoints.toLocaleString()} points)`);
|
||||
console.log(` 🏛️ Original Share: ${royaltyShare.originalPercentage.toFixed(2)}% (${royaltyShare.originalPoints.toLocaleString()} points)`);
|
||||
console.log(` 💰 Total Royalty: 33% of NFT sales`);
|
||||
|
||||
// Only create split if minter gets more than 0%
|
||||
if (royaltyShare.minterPoints > 0) {
|
||||
console.log(`\n🚀 CREATING SPLIT ROYALTY ADDRESS...`);
|
||||
console.log(` 📤 Calling SplitXCH API...`);
|
||||
|
||||
splitRoyaltyInfo = await createSplitRoyaltyAddress(
|
||||
originalRoyaltyAddress,
|
||||
targetWallet,
|
||||
royaltyShare.minterPoints
|
||||
);
|
||||
finalRoyaltyAddress = splitRoyaltyInfo.address;
|
||||
|
||||
console.log(`\n✅ SPLIT ROYALTY SUCCESS!`);
|
||||
console.log(` 🎉 New Split Address: ${finalRoyaltyAddress}`);
|
||||
console.log(` 🆔 Split ID: ${splitRoyaltyInfo.splitId}`);
|
||||
console.log(` 💎 This address will automatically distribute royalties based on magic level!`);
|
||||
} else {
|
||||
console.log(`\n⚪ NO SPLIT NEEDED:`);
|
||||
console.log(` 📊 Magic value ${magicValue} results in 0% for minter`);
|
||||
console.log(` 🏛️ Using original royalty address: ${originalRoyaltyAddress}`);
|
||||
}
|
||||
} catch (splitError) {
|
||||
console.log(`\n❌ SPLIT ROYALTY ERROR:`);
|
||||
console.error(` 🚨 Failed to create split royalty address: ${splitError.message}`);
|
||||
console.log(` 🔄 Falling back to original royalty address: ${originalRoyaltyAddress}`);
|
||||
// Continue with original address as fallback
|
||||
}
|
||||
|
||||
console.log('\n💎 ═══════════════════════════════════════════════════════════════════════════════════════ 💎\n');
|
||||
} else {
|
||||
console.log('\n💰 ─────────────────────── ROYALTY ADDRESS SELECTION ───────────────────────');
|
||||
console.log('💰 Using original royalty address - no split needed');
|
||||
console.log(`💰 Reason: ${!targetWallet ? 'No target wallet provided' :
|
||||
targetWallet === originalRoyaltyAddress ? 'Target wallet same as original' :
|
||||
object.className !== 'DRACATTUS' ? 'Not a DRACATTUS object' : 'Unknown'}`);
|
||||
console.log(`💰 Address: ${originalRoyaltyAddress}`);
|
||||
console.log('💰 ─────────────────────────────────────────────────────────────────────────\n');
|
||||
}
|
||||
|
||||
// Construct the mint request body
|
||||
const mintRequestBody = {
|
||||
profile_id: mintgardenProfileId,
|
||||
@@ -177,8 +356,8 @@ Parse.Cloud.define('mintAsset', async (request) => {
|
||||
edition_total: seriesTotal
|
||||
},
|
||||
target_address: targetAddress,
|
||||
royalty_address: royaltyAddress,
|
||||
royalty_percentage: 33,
|
||||
royalty_address: finalRoyaltyAddress,
|
||||
royalty_percentage: royaltyPercentage,
|
||||
reserve_for_seconds:60
|
||||
};
|
||||
|
||||
@@ -197,8 +376,23 @@ Parse.Cloud.define('mintAsset', async (request) => {
|
||||
body: JSON.stringify(mintRequestBody)
|
||||
});
|
||||
|
||||
// Log the request body for debugging
|
||||
console.log('Mint request body:', JSON.stringify(mintRequestBody, null, 2));
|
||||
// Log the final mint configuration with enhanced royalty info
|
||||
console.log('\n🚀 ═══════════════════════════════════════════════════════════════════════════════════════ 🚀');
|
||||
console.log('🚀 🎯 FINAL MINT CONFIGURATION 🎯 🚀');
|
||||
console.log('🚀 ═══════════════════════════════════════════════════════════════════════════════════════ 🚀');
|
||||
console.log(`\n📋 MINT DETAILS:`);
|
||||
console.log(` 🎨 NFT Target: ${targetAddress}`);
|
||||
console.log(` 👑 Royalty Address: ${finalRoyaltyAddress}`);
|
||||
console.log(` 💎 Royalty Percentage: ${royaltyPercentage}%`);
|
||||
if (splitRoyaltyInfo) {
|
||||
console.log(` 🔀 Split Type: Magic-Based Split (${object.get('magic')}/100 magic)`);
|
||||
console.log(` 🆔 Split ID: ${splitRoyaltyInfo.splitId}`);
|
||||
} else {
|
||||
console.log(` 🔀 Split Type: Single Address (No Split)`);
|
||||
}
|
||||
console.log(`\n📄 Complete Mint Request Body:`);
|
||||
console.log(JSON.stringify(mintRequestBody, null, 2));
|
||||
console.log('\n🚀 ═══════════════════════════════════════════════════════════════════════════════════════ 🚀\n');
|
||||
|
||||
if (!response.ok) {
|
||||
const responseText = await response.text(); // Get raw response text
|
||||
@@ -226,8 +420,23 @@ Parse.Cloud.define('mintAsset', async (request) => {
|
||||
throw new Error('Unable to parse MintGarden API response');
|
||||
}
|
||||
|
||||
// Log the successful mint
|
||||
console.log('Successfully minted NFT:', mintResult);
|
||||
// Log the successful mint with enhanced royalty details
|
||||
console.log('\n🎉 ═══════════════════════════════════════════════════════════════════════════════════════ 🎉');
|
||||
console.log('🎉 ✅ MINT SUCCESS! ✅ 🎉');
|
||||
console.log('🎉 ═══════════════════════════════════════════════════════════════════════════════════════ 🎉');
|
||||
console.log(`\n🏆 MINT RESULTS:`);
|
||||
console.log(` 🆔 NFT ID: ${mintResult.nft_id}`);
|
||||
console.log(` 🎨 Minted To: ${targetAddress}`);
|
||||
console.log(` 👑 Royalty Setup: ${finalRoyaltyAddress}`);
|
||||
if (splitRoyaltyInfo) {
|
||||
console.log(` 💎 Royalty Type: Split Royalty (Magic: ${object.get('magic')}/100)`);
|
||||
console.log(` 🔀 Split Details: ${splitRoyaltyInfo.minterPoints} pts → Minter, ${splitRoyaltyInfo.originalPoints} pts → Original`);
|
||||
} else {
|
||||
console.log(` 💎 Royalty Type: Single Address (${royaltyPercentage}% to ${finalRoyaltyAddress})`);
|
||||
}
|
||||
console.log(`\n📊 Full MintGarden Response:`);
|
||||
console.log(mintResult);
|
||||
console.log('\n🎉 ═══════════════════════════════════════════════════════════════════════════════════════ 🎉\n');
|
||||
|
||||
// Save mint record to Parse
|
||||
const MintRecord = Parse.Object.extend('MintRecord');
|
||||
@@ -244,8 +453,11 @@ Parse.Cloud.define('mintAsset', async (request) => {
|
||||
status: 'success',
|
||||
timestamp: new Date(),
|
||||
targetWallet: targetAddress,
|
||||
royaltyAddress: royaltyAddress,
|
||||
royaltyPercentage: 5,
|
||||
royaltyAddress: finalRoyaltyAddress,
|
||||
royaltyPercentage: royaltyPercentage, // Fixed: Now logs actual percentage used (33%)
|
||||
originalRoyaltyAddress: originalRoyaltyAddress,
|
||||
splitRoyaltyInfo: splitRoyaltyInfo,
|
||||
magicValue: object.className === 'DRACATTUS' ? (object.get('magic') || 0) : null,
|
||||
profileId: mintgardenProfileId,
|
||||
requested_mojos: requested_mojos ? parseInt(requested_mojos, 10) : null,
|
||||
network: isMainnet ? 'mainnet' : 'testnet' // Track which network was used
|
||||
@@ -253,6 +465,22 @@ Parse.Cloud.define('mintAsset', async (request) => {
|
||||
|
||||
await mintRecord.save(null, { useMasterKey: true });
|
||||
|
||||
// Prepare detailed royalty information for client
|
||||
let royaltyDetails = {
|
||||
address: finalRoyaltyAddress,
|
||||
percentage: royaltyPercentage,
|
||||
type: splitRoyaltyInfo ? 'split' : 'single',
|
||||
splitInfo: splitRoyaltyInfo
|
||||
};
|
||||
|
||||
// Add enhanced split details if this was a DRACATTUS with split royalties
|
||||
if (royaltyCalculationResults) {
|
||||
royaltyDetails.splitCalculation = {
|
||||
...royaltyCalculationResults,
|
||||
wasActuallySplit: !!splitRoyaltyInfo
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: mintResult,
|
||||
@@ -260,6 +488,7 @@ Parse.Cloud.define('mintAsset', async (request) => {
|
||||
dataHash,
|
||||
metadataHash
|
||||
},
|
||||
royalty: royaltyDetails,
|
||||
network: isMainnet ? 'mainnet' : 'testnet'
|
||||
};
|
||||
|
||||
@@ -267,10 +496,10 @@ Parse.Cloud.define('mintAsset', async (request) => {
|
||||
console.error('Error minting asset:', error);
|
||||
|
||||
// Get royalty address from config
|
||||
let royaltyAddress = null;
|
||||
let originalRoyaltyAddress = null;
|
||||
try {
|
||||
const config = await Parse.Config.get({ useMasterKey: true });
|
||||
royaltyAddress = config.get('DRAC_MINTGARDEN_ROYALY_ADDRESS');
|
||||
originalRoyaltyAddress = config.get('DRAC_MINTGARDEN_ROYALY_ADDRESS');
|
||||
} catch (configError) {
|
||||
console.error('Error fetching config:', configError);
|
||||
}
|
||||
@@ -285,8 +514,8 @@ Parse.Cloud.define('mintAsset', async (request) => {
|
||||
status: 'failed',
|
||||
timestamp: new Date(),
|
||||
targetAddress: request.params.targetWallet || null,
|
||||
royaltyAddress: royaltyAddress,
|
||||
royaltyPercentage: 5,
|
||||
royaltyAddress: originalRoyaltyAddress,
|
||||
royaltyPercentage: 33, // Fixed: Now logs actual percentage used (33%)
|
||||
network: request.params.isMainnet ? 'mainnet' : 'testnet'
|
||||
});
|
||||
|
||||
|
||||
@@ -530,8 +530,8 @@ function startDexieWebSocketListener(saveAllItems = false) {
|
||||
}
|
||||
}
|
||||
|
||||
// Summary every 25 messages
|
||||
if (messageCounter % 25 === 0) {
|
||||
// Summary at milestones (100, 500, 1000, then every 1000)
|
||||
if (messageCounter === 100 || messageCounter === 500 || messageCounter % 1000 === 0) {
|
||||
await log(`📊 Processed ${messageCounter} events`);
|
||||
}
|
||||
} catch (parseError) {
|
||||
|
||||
@@ -175,8 +175,8 @@ Parse.Cloud.define('sendDracattusCreatedEmail', async (request) => {
|
||||
const mockDracattusData = {
|
||||
id: 'TEST123456',
|
||||
name: request.params?.dracattusName || 'Mystical Fire Dragon',
|
||||
type: 'Legendary Dracattus',
|
||||
rarity: 'Legendary',
|
||||
type: 'Dracattus',
|
||||
rarity: 'Common',
|
||||
thumbnail: 'https://api.dracattus.com/v1/files/koba42/72e24849ca75695f0b324f4a177d5dc4_1.webp',
|
||||
createdAt: new Date().toLocaleDateString()
|
||||
};
|
||||
|
||||
@@ -134,7 +134,7 @@ const dashboard = new ParseDashboard({
|
||||
requireRevocableSessions: true,
|
||||
expireInactiveSessions: true,
|
||||
logsFolder: './logs',
|
||||
logLevel: 'info',
|
||||
logLevel: 'warn',
|
||||
maxUploadSize: '100mb',
|
||||
allowExpiredAuthDataToken: false,
|
||||
encodeParseObjectInCloudFunction: true,
|
||||
@@ -191,9 +191,9 @@ const dashboard = new ParseDashboard({
|
||||
keepAlive: true,
|
||||
keepAliveInitialDelay: 10000
|
||||
},
|
||||
logLevels: ['error', 'warn', 'info', 'verbose']
|
||||
logLevels: ['error', 'warn']
|
||||
},
|
||||
verbose: true,
|
||||
verbose: false,
|
||||
startLiveQueryServer: true,
|
||||
websocketTimeout: 100 * 1000
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user