UNPKG

@flipflop-sdk/node

Version:

FlipFlop Node.js SDK for programmatic token operations

227 lines 8.23 kB
"use strict"; /** * Update name, symbol and image to irys to get metadata uri * This module handles the complete metadata upload process: * 1. Validate image file type and size * 2. Upload image to Irys network * 3. Create metadata JSON with image URL and token info * 4. Upload metadata JSON to Irys network * 5. Return final metadata URL */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.generateMetadataUri = exports.getMimeType = exports.createAndUploadMetadata = exports.uploadToStorage = exports.validateImageFile = void 0; const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const axios_1 = __importDefault(require("axios")); const form_data_1 = __importDefault(require("form-data")); const config_1 = require("./config"); // Constants based on frontend configuration const VALID_IMAGE_TYPES = [ "image/jpeg", "image/jpg", "image/png", "image/gif", "image/webp", "image/avif", ]; const MAX_AVATAR_FILE_SIZE = 0.25 * 1024 * 1024; // 250KB /** * Validates image file type and size based on frontend validation logic * @param imagePath Path to the image file * @returns Object with validation result and error message if any */ const validateImageFile = (imagePath) => { try { // Check if file exists if (!fs_1.default.existsSync(imagePath)) { return { valid: false, error: "Image file does not exist" }; } // Get file stats const stats = fs_1.default.statSync(imagePath); // Check file size (250KB limit) if (stats.size > MAX_AVATAR_FILE_SIZE) { return { valid: false, error: `Image size ${(stats.size / 1024 / 1024).toFixed(2)}MB exceeds limit of ${MAX_AVATAR_FILE_SIZE / 1024 / 1024}MB`, }; } // Check file type using extension and mime type detection const extension = path_1.default.extname(imagePath).toLowerCase(); const mimeTypeMap = { ".jpg": "image/jpeg", ".jpeg": "image/jpeg", ".png": "image/png", ".gif": "image/gif", ".webp": "image/webp", ".avif": "image/avif", }; const mimeType = mimeTypeMap[extension]; if (!mimeType || !VALID_IMAGE_TYPES.includes(mimeType)) { return { valid: false, error: `Invalid image format. Supported formats: ${VALID_IMAGE_TYPES.join(", ")}`, }; } return { valid: true }; } catch (error) { return { valid: false, error: `Error validating image: ${error instanceof Error ? error.message : "Unknown error"}`, }; } }; exports.validateImageFile = validateImageFile; /** * Uploads file to Irys network * @param filePath Path to the file to upload * @param action Type of upload (avatar, banner, metadata) * @returns Promise resolving to the uploaded file URL */ const uploadToStorage = async (config, filePath, action = "avatar") => { const uploadApiUrl = `${config.apiBaseUrl}/api/irys/upload`; try { const formData = new form_data_1.default(); // Read file as buffer const fileBuffer = fs_1.default.readFileSync(filePath); const fileName = path_1.default.basename(filePath); const mimeType = getMimeType(filePath); formData.append("file", fileBuffer, { filename: fileName, contentType: mimeType, }); formData.append("action", action); const response = await axios_1.default.post(uploadApiUrl, formData, { headers: { ...formData.getHeaders(), }, }); if (response.data.status === "success") { const itemId = response.data.fileInfo.itemId; return `${config.irysGatewayUrl}/${itemId}`; } else { throw new Error(`Upload failed: ${JSON.stringify(response.data)}`); } } catch (error) { console.error("Error uploading to storage:", error); throw error; } }; exports.uploadToStorage = uploadToStorage; /** * Determines MIME type based on file extension * @param filePath Path to the file * @returns MIME type string */ const getMimeType = (filePath) => { const extension = path_1.default.extname(filePath).toLowerCase(); const mimeTypeMap = { ".jpg": "image/jpeg", ".jpeg": "image/jpeg", ".png": "image/png", ".gif": "image/gif", ".webp": "image/webp", ".avif": "image/avif", ".json": "application/json", }; return mimeTypeMap[extension] || "application/octet-stream"; }; exports.getMimeType = getMimeType; /** * Creates metadata JSON object and uploads it to Irys * @param params Metadata parameters * @param imageUrl URL of the uploaded image * @returns Promise resolving to the metadata URL */ const createAndUploadMetadata = async (config, params, imageUrl) => { const metadata = { name: params.name, symbol: params.symbol, description: params.description === undefined ? "" : params.description, image: imageUrl, extensions: { website: "", twitter: "", discord: "", telegram: "", github: "", medium: "", }, }; // Create temporary metadata file const tempDir = path_1.default.join(process.cwd(), "temp"); if (!fs_1.default.existsSync(tempDir)) { fs_1.default.mkdirSync(tempDir, { recursive: true }); } const metadataPath = path_1.default.join(tempDir, "metadata.json"); fs_1.default.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2)); try { const metadataUrl = await uploadToStorage(config, metadataPath, "metadata"); // Clean up temporary file fs_1.default.unlinkSync(metadataPath); return metadataUrl; } catch (error) { // Clean up on error if (fs_1.default.existsSync(metadataPath)) { fs_1.default.unlinkSync(metadataPath); } throw error; } }; exports.createAndUploadMetadata = createAndUploadMetadata; /** * Main function to generate metadata URI from command line parameters * @param name Token name * @param symbol Token symbol * @param description Token description * @param imagePath Path to the image file * @returns Promise resolving to metadata upload result */ const generateMetadataUri = async (options) => { try { const config = config_1.CONFIGS[(0, config_1.getNetworkType)(options.rpc)]; // Step 1: Validate image file // console.log('Step 1: Validating image file...'); const validation = validateImageFile(options.imagePath); if (!validation.valid) { return { success: false, message: validation.error, }; } // Step 2: Upload image to Irys // console.log('Step 2: Uploading image to Irys network...'); const imageUrl = await uploadToStorage(config, options.imagePath, "avatar"); // console.log(`Image uploaded successfully: ${imageUrl}`); // Step 3: Create and upload metadata // console.log('Step 3: Creating and uploading metadata...'); const metadataUrl = await createAndUploadMetadata(config, { name: options.name, symbol: options.symbol, description: options.description, }, imageUrl); // console.log(`Metadata uploaded successfully: ${metadataUrl}`); return { success: true, data: { imageUrl, metadataUrl, }, }; } catch (error) { console.error("Error generating metadata URI:", error); return { success: false, message: error instanceof Error ? error.message : "Unknown error occurred", }; } }; exports.generateMetadataUri = generateMetadataUri; //# sourceMappingURL=metadata.js.map