Files
pwap/shared/lib/ipfs.ts
T
pezkuwichain a635610b7c feat: Phase 1B complete - Perwerde & ValidatorPool UI
Perwerde (Education Platform):
- Add hybrid backend (Supabase + Blockchain + IPFS)
- Implement CourseList, CourseCreator, StudentDashboard
- Create courses table with RLS policies
- Add IPFS upload utility
- Integrate with pallet-perwerde extrinsics

ValidatorPool:
- Add validator pool management UI
- Implement PoolCategorySelector with 3 categories
- Add ValidatorPoolDashboard with pool stats
- Integrate with pallet-validator-pool extrinsics
- Add to StakingDashboard as new tab

Technical:
- Fix all toast imports (sonner)
- Fix IPFS File upload (Blob conversion)
- Fix RLS policies (wallet_address → auth.uid)
- Add error boundaries
- Add loading states

Status: UI complete, blockchain integration pending VPS deployment
2025-11-17 05:04:51 +03:00

40 lines
1.1 KiB
TypeScript

import { toast } from 'sonner';
const PINATA_JWT = import.meta.env.VITE_PINATA_JWT;
const PINATA_API = 'https://api.pinata.cloud/pinning/pinFileToIPFS';
export async function uploadToIPFS(file: File): Promise<string> {
if (!PINATA_JWT || PINATA_JWT === 'your_pinata_jwt_here') {
throw new Error('Pinata JWT not configured. Set VITE_PINATA_JWT in .env');
}
const formData = new FormData();
formData.append('file', file);
try {
const response = await fetch(PINATA_API, {
method: 'POST',
headers: {
'Authorization': `Bearer ${PINATA_JWT}`,
},
body: formData,
});
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
throw new Error(errorData.error || `Upload failed: ${response.statusText}`);
}
const data = await response.json();
return data.IpfsHash; // Returns: Qm...
} catch (error) {
console.error('IPFS upload error:', error);
toast.error('Failed to upload to IPFS');
throw error;
}
}
export function getIPFSUrl(hash: string): string {
return `https://gateway.pinata.cloud/ipfs/${hash}`;
}