Open
Description
uploadutils.ts
import type { NextApiRequest, NextApiResponse } from 'next'
import formidable from 'formidable'
import fs from 'fs'
import { create } from '@web3-storage/w3up-client'
import * as Signer from '@ucanto/principal/ed25519'
import * as Proof from '@web3-storage/w3up-client/proof'
import { StoreMemory } from '@web3-storage/w3up-client/stores/memory'
export const config = {
api: {
bodyParser: false,
},
}
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method !== 'POST') {
return res.status(405).json({ message: 'Method not allowed' })
}
const form = formidable();
try {
const [fields, files] = await form.parse(req);
const file = files.file?.[0];
if (!file) {
return res.status(400).json({ error: 'No file uploaded' })
}
const fileContent = await fs.promises.readFile(file.filepath);
// Create a File object from the uploaded file
const fileObject = new File(
[fileContent],
file.originalFilename || 'unnamed_file',
{ type: file.mimetype || 'application/octet-stream' }
);
// Initialize Storacha client
const client = await initStorachaClient();
if (!client) {
return res.status(500).json({ error: 'Failed to initialize storage client' });
}
// Upload file to Storacha
const cid = await client.uploadFile(fileObject);
// Construct the URL to access the file
const url = `https://${cid}.ipfs.w3s.link`;
res.status(200).json({ url });
} catch (error) {
console.error('Error uploading to IPFS:', error);
res.status(500).json({ error: 'Failed to upload image to IPFS' });
}
}
async function initStorachaClient() {
try {
// Get the private key and proof from environment variables
const privateKey = process.env.STORACHA_PRIVATE_KEY;
const proof = process.env.STORACHA_PROOF;
if (!privateKey || !proof) {
console.error('Missing Storacha credentials');
return null;
}
// Parse the private key to create a signer
const principal = Signer.parse(privateKey);
// Create a memory store (since this is a serverless function)
const store = new StoreMemory();
// Create the client with the principal and store
const client = await create({ principal, store });
// Parse the proof and add the space to the client
const parsedProof = await Proof.parse(proof);
const space = await client.addSpace(parsedProof);
// Set the space as the current space
await client.setCurrentSpace(space.did());
return client;
} catch (error) {
console.error('Error initializing Storacha client:', error);
return null;
}
}
this is how i create my cred
gencre.ts
#!/usr/bin/env ts-node
/**
* Storacha Network Credentials Generator
*
* This script automates the process of generating credentials for Storacha Network
* (formerly Web3.Storage) with minimal user interaction.
*/
// @ts-nocheck
/* eslint-disable */
// The above directives disable TypeScript checking for this file
// Import the required modules
const fs = require('fs');
const path = require('path');
const readline = require('readline');
const { execSync } = require('child_process');
// Create readline interface for user input
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
// Promisify the question function
function question(query) {
return new Promise((resolve) => {
rl.question(query, resolve);
});
}
// Function to extract data from command output
function extractFromOutput(output, pattern) {
const match = output.match(pattern);
return match ? match[1] : null;
}
async function main() {
try {
console.log('\n🔥 Storacha Network Automated Setup 🔥\n');
// Install w3cli if needed
try {
execSync('npx w3 --version', { stdio: 'ignore' });
} catch (error) {
console.log('⏳ Installing w3cli...');
execSync('npm install -g @web3-storage/w3cli', { stdio: 'inherit' });
}
// Get user email
const email = await question('Enter your email address: ');
if (!email || !email.includes('@')) {
console.error('❌ Invalid email address. Please provide a valid email.');
process.exit(1);
}
// Step 1: Create a key and capture the output
console.log('\n⏳ Creating a key...');
const keyOutput = execSync('npx w3 key create', { encoding: 'utf8' });
console.log('✅ Key created successfully!');
// Extract DID and private key
const did = keyOutput.match(/did:key:([a-zA-Z0-9]+)/)?.[0];
const privateKey = keyOutput.trim().split('\n')[1]?.trim();
if (!did || !privateKey) {
console.error('❌ Could not extract DID or private key from output.');
console.log('Key output:', keyOutput);
process.exit(1);
}
console.log(`✅ DID: ${did}`);
// Step 2: Login with email
console.log(`\n⏳ Logging in with email ${email}...`);
console.log('🔔 An email will be sent to your address. Please check your inbox and click the verification link.');
execSync(`npx w3 login ${email}`, { stdio: 'inherit' });
// Wait for user to verify email
await question('Press Enter after you have clicked the verification link in your email...');
// Step 3: Create a space
console.log('\n⏳ Creating a space...');
execSync('npx w3 space create bondle-app-space', { stdio: 'inherit' });
console.log('✅ Space created successfully!');
// Step 4: Generate delegation proof
console.log('\n⏳ Generating delegation proof...');
// Create a temporary file to capture the output
const tempFile = path.join(process.cwd(), 'temp-delegation.txt');
try {
execSync(`npx w3 delegation create ${did} --can "store/*" --can "upload/*" --base64 > "${tempFile}" 2>&1`, { stdio: 'inherit' });
// Read the delegation proof from the file
let proof = fs.readFileSync(tempFile, 'utf8').trim();
// Clean up the proof - remove any non-base64 characters
proof = proof.replace(/[^A-Za-z0-9+/=]/g, '');
if (!proof) {
throw new Error('Could not extract delegation proof');
}
console.log('✅ Delegation proof generated successfully!');
// Save credentials to .env.local
const rootDir = process.cwd();
const envPath = path.join(rootDir, '.env.local');
// Check if .env.local already exists
let envContent = '';
if (fs.existsSync(envPath)) {
envContent = fs.readFileSync(envPath, 'utf8');
// Remove existing Storacha credentials if they exist
envContent = envContent
.replace(/^STORACHA_PRIVATE_KEY=.*$/m, '')
.replace(/^STORACHA_PROOF=.*$/m, '')
.replace(/^STORACHA_DID=.*$/m, '')
.replace(/\n\n+/g, '\n\n'); // Clean up multiple empty lines
}
// Add the new credentials
const newEnvContent =
`${envContent.trim()}
# Storacha Network (formerly Web3.Storage) credentials
STORACHA_PRIVATE_KEY=${privateKey}
STORACHA_PROOF=${proof}
STORACHA_DID=${did}
`;
fs.writeFileSync(envPath, newEnvContent);
console.log('\n✅ Credentials saved to .env.local successfully!');
console.log('\n🎉 Setup complete! You can now use Storacha Network for file uploads.');
console.log('\nThe following credentials have been saved:');
console.log(`- Private Key: ${privateKey.substring(0, 10)}...${privateKey.substring(privateKey.length - 5)}`);
console.log(`- DID: ${did}`);
console.log(`- Proof: ${proof.substring(0, 10)}...${proof.substring(proof.length - 5)}`);
} finally {
// Clean up temporary file
if (fs.existsSync(tempFile)) {
fs.unlinkSync(tempFile);
}
}
} catch (error) {
console.error('\n❌ An error occurred:', error);
console.log('\nTroubleshooting tips:');
console.log('1. Make sure you have a stable internet connection');
console.log('2. Verify that you entered a valid email address');
console.log('3. Check if you clicked the verification link in the email');
console.log('4. Try running the script again');
} finally {
rl.close();
}
}
main();
anyways when i run the upload-util.ts
i get this error.
<!DOCTYPE html>
<html lang="en">
<head>
<style data-next-hide-fouc="true">
body {
display: none
}
</style>
<noscript data-next-hide-fouc="true">
<style>
body {
display: block
}
</style>
</noscript>
<meta charSet="utf-8"/>
<meta name="viewport" content="width=device-width"/>
<meta name="next-head-count" content="2"/>
<noscript data-n-css=""></noscript>
<script defer="" nomodule="" src="/_next/static/chunks/polyfills.js"></script>
<script src="/_next/static/chunks/webpack.js" defer=""></script>
<script src="/_next/static/chunks/main.js" defer=""></script>
<script src="/_next/static/chunks/pages/_app.js" defer=""></script>
<script src="/_next/static/chunks/pages/_error.js" defer=""></script>
<script src="/_next/static/development/_buildManifest.js" defer=""></script>
<script src="/_next/static/development/_ssgManifest.js" defer=""></script>
<noscript id="__next_css__DO_NOT_USE__"></noscript>
</head>
<body>
<div id="__next"></div>
<script src="/_next/static/chunks/react-refresh.js"></script>
<script id="__NEXT_DATA__" type="application/json">
{
"props": {
"pageProps": {
"statusCode": 500
}
},
"page": "/_error",
"query": {
},
"buildId": "development",
"isFallback": false,
"err": {
"name": "Error",
"source": "server",
"message": "Package subpath './link' is not defined by \"exports\" in C:\\Users\\Charles\\Desktop\\DEX\\Attempt\\PIMP CLONE\\pump-fun-ui\\node_modules\\multiformats\\package.json imported from C:\\Users\\Charles\\Desktop\\DEX\\Attempt\\PIMP CLONE\\pump-fun-ui\\node_modules\\@web3-storage\\w3up-client\\dist\\src\\proof.js",
"stack": "Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './link' is not defined by \"exports\" in C:\\Users\\Charles\\Desktop\\DEX\\Attempt\\PIMP CLONE\\pump-fun-ui\\node_modules\\multiformats\\package.json imported from C:\\Users\\Charles\\Desktop\\DEX\\Attempt\\PIMP CLONE\\pump-fun-ui\\node_modules\\@web3-storage\\w3up-client\\dist\\src\\proof.js\n at new NodeError (node:internal/errors:405:5)\n at exportsNotFound (node:internal/modules/esm/resolve:366:10)\n at packageExportsResolve (node:internal/modules/esm/resolve:713:9)\n at packageResolve (node:internal/modules/esm/resolve:899:14)\n at moduleResolve (node:internal/modules/esm/resolve:973:20)\n at defaultResolve (node:internal/modules/esm/resolve:1193:11)\n at ModuleLoader.defaultResolve (node:internal/modules/esm/loader:404:12)\n at ModuleLoader.resolve (node:internal/modules/esm/loader:373:25)\n at ModuleLoader.getModuleJob (node:internal/modules/esm/loader:250:38)\n at ModuleWrap.\u003canonymous\u003e (node:internal/modules/esm/module_job:76:39)\n at link (node:internal/modules/esm/module_job:75:36)"
},
"gip": true,
"scriptLoader": [
]
}</script>
</body>
</html>