UNPKG

@wttp/site

Version:

Web3 Transfer Protocol (WTTP) - Site Contracts and deployment tools

241 lines • 10.3 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.uploadToArweave = uploadToArweave; exports.uploadToArweaveStandalone = uploadToArweaveStandalone; const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const arweave_1 = __importDefault(require("arweave")); const generateManifest_1 = require("./generateManifest"); /** * Upload files marked for Arweave storage to Arweave using official Arweave library * Updates the manifest with actual Arweave transaction IDs * * @param manifestPath Path to the manifest file (will be updated in place) * @param options Upload options including wallet and source path * @returns Upload result with TXIDs */ async function uploadToArweave(manifestPath, options = {}) { const { walletPath, wallet, sourcePath, uploadManifest = false } = options; // Load manifest if (!fs_1.default.existsSync(manifestPath)) { throw new Error(`Manifest file not found: ${manifestPath}`); } const manifest = (0, generateManifest_1.loadManifest)(manifestPath); // Determine source path const baseSourcePath = sourcePath || path_1.default.dirname(manifestPath); // Initialize Arweave const arweave = arweave_1.default.init({ host: "arweave.net", port: 443, protocol: "https", }); // Load wallet let walletKey; if (wallet) { walletKey = wallet; } else if (walletPath) { if (!fs_1.default.existsSync(walletPath)) { throw new Error(`Arweave wallet file not found: ${walletPath}`); } walletKey = JSON.parse(fs_1.default.readFileSync(walletPath, "utf-8")); } else { throw new Error("Either walletPath or wallet must be provided"); } console.log(`šŸ“¦ Starting Arweave upload for manifest: ${manifestPath}`); console.log(`šŸ“ Source directory: ${baseSourcePath}`); // Find files marked for Arweave storage const arweaveFiles = manifest.siteData.files.filter((file) => file.externalStorage === "arweave"); if (arweaveFiles.length === 0) { console.log(`ā„¹ļø No files marked for Arweave storage in manifest`); return { filesUploaded: 0, filesSkipped: 0, txIds: new Map(), }; } console.log(`šŸ“„ Found ${arweaveFiles.length} files to upload to Arweave`); const txIds = new Map(); let filesUploaded = 0; let filesSkipped = 0; // Upload each file for (let i = 0; i < arweaveFiles.length; i++) { const file = arweaveFiles[i]; // Check if already has a TXID (from previous upload) const currentLocation = file.redirect?.location || ""; const existingTxId = currentLocation.replace(/^ar:\/\//, "").replace(/^arweave:\/\//, ""); if (existingTxId && existingTxId !== "[pending]" && existingTxId.length === 43) { // Valid Arweave TXID format (43 characters base64url) console.log(`ā­ļø Skipping ${file.path} - already has TXID: ${existingTxId}`); txIds.set(file.path, existingTxId); filesSkipped++; continue; } // Resolve file path const fileRelativePath = file.path.replace(/^\.\//, ""); const fileAbsolutePath = path_1.default.join(baseSourcePath, fileRelativePath); if (!fs_1.default.existsSync(fileAbsolutePath)) { console.warn(`āš ļø File not found: ${fileAbsolutePath} - skipping`); continue; } console.log(`\nšŸ“¤ Uploading ${i + 1}/${arweaveFiles.length}: ${file.path}`); console.log(` Type: ${file.type}, Size: ${file.size} bytes`); try { // Read file data const fileData = fs_1.default.readFileSync(fileAbsolutePath); // Create transaction const transaction = await arweave.createTransaction({ data: fileData, }); // Add tags transaction.addTag("Content-Type", file.type); transaction.addTag("File-Path", file.path); if (file.charset) { transaction.addTag("Charset", file.charset); } // Sign transaction await arweave.transactions.sign(transaction, walletKey); // Post transaction const uploader = await arweave.transactions.getUploader(transaction); while (!uploader.isComplete) { await uploader.uploadChunk(); console.log(` šŸ“¤ Upload progress: ${uploader.pctComplete}%`); } const txId = transaction.id; console.log(` āœ… Uploaded! TXID: ${txId}`); // Update manifest if (!file.redirect) { file.redirect = { code: 301, location: `ar://${txId}`, }; } else { file.redirect.location = `ar://${txId}`; } file.status = "uploaded"; txIds.set(file.path, txId); filesUploaded++; // Save manifest after each upload (in case of interruption) (0, generateManifest_1.saveManifest)(manifest, manifestPath); } catch (error) { console.error(` āŒ Failed to upload ${file.path}:`, error); file.status = "error"; throw error; } } // Save updated manifest (0, generateManifest_1.saveManifest)(manifest, manifestPath); console.log(`\nāœ… Arweave upload complete!`); console.log(` Files uploaded: ${filesUploaded}`); console.log(` Files skipped: ${filesSkipped}`); let manifestTxId; // Optionally upload the manifest itself if (uploadManifest) { console.log(`\nšŸ“¤ Uploading manifest to Arweave...`); try { const manifestData = JSON.stringify(manifest, null, 2); const manifestBuffer = Buffer.from(manifestData, "utf-8"); // Create transaction for manifest const manifestTransaction = await arweave.createTransaction({ data: manifestBuffer, }); // Add tags manifestTransaction.addTag("Content-Type", "application/json"); manifestTransaction.addTag("Manifest-Name", manifest.name); manifestTransaction.addTag("Protocol", "wttp"); // Sign transaction await arweave.transactions.sign(manifestTransaction, walletKey); // Post transaction const manifestUploader = await arweave.transactions.getUploader(manifestTransaction); while (!manifestUploader.isComplete) { await manifestUploader.uploadChunk(); console.log(` šŸ“¤ Upload progress: ${manifestUploader.pctComplete}%`); } manifestTxId = manifestTransaction.id; console.log(` āœ… Manifest uploaded! TXID: ${manifestTxId}`); } catch (error) { console.error(` āŒ Failed to upload manifest:`, error); } } return { filesUploaded, filesSkipped, txIds, manifestTxId, }; } /** * Standalone function to upload files to Arweave (can be used outside Hardhat) * * @param manifestPathOrConfig Either a path to manifest file, or a ManifestConfig object * @param sourcePath Source directory path (required if generating manifest) * @param options Upload options * @returns Upload result */ async function uploadToArweaveStandalone(manifestPathOrConfig, sourcePath, options = {}) { const { generateManifestStandalone, saveManifest } = await Promise.resolve().then(() => __importStar(require("./generateManifest"))); let manifest; let manifestPath; if (typeof manifestPathOrConfig === "string") { // Load existing manifest manifestPath = manifestPathOrConfig; manifest = (0, generateManifest_1.loadManifest)(manifestPath); // Use source path from options or manifest directory if (!options.sourcePath) { options.sourcePath = path_1.default.dirname(manifestPath); } } else { // Generate manifest from config if (!sourcePath) { throw new Error("sourcePath is required when providing ManifestConfig"); } const config = manifestPathOrConfig; const outputPath = path_1.default.join(sourcePath, "wttp.manifest.json"); manifest = await generateManifestStandalone(sourcePath, "/", config); manifestPath = saveManifest(manifest, outputPath); options.sourcePath = sourcePath; } return uploadToArweave(manifestPath, options); } //# sourceMappingURL=uploadToArweave.js.map