zurri / src /services /ipfsService.ts
nexusbert's picture
push
ef85da9
import { PinataSDK } from 'pinata';
export class IpfsService {
private pinata: PinataSDK | null;
private gatewayUrl: string;
constructor() {
const pinataJwt = process.env.PINATA_JWT || '';
const gatewayUrl = process.env.GATEWAY_URL || '';
if (!pinataJwt) {
console.warn('PINATA_JWT not set - IPFS features will be disabled');
this.pinata = null;
this.gatewayUrl = '';
} else {
const gatewayDomain = gatewayUrl
? gatewayUrl.replace(/^https?:\/\//, '').replace(/\/ipfs\/?$/, '')
: 'gateway.pinata.cloud';
this.gatewayUrl = `https://${gatewayDomain}/ipfs/`;
if (!gatewayUrl) {
console.warn('GATEWAY_URL not set - using default Pinata gateway');
}
this.pinata = new PinataSDK({
pinataJwt: pinataJwt,
pinataGateway: gatewayDomain,
});
}
}
async uploadMetadata(metadata: {
name: string;
description: string;
endpoint: string;
price: number;
creatorId: string;
category?: string;
capabilities?: string[];
metadata?: Record<string, any>;
}): Promise<string> {
if (!this.pinata) {
throw new Error('Pinata JWT not configured');
}
try {
// Convert metadata object to JSON string for upload
const jsonString = JSON.stringify(metadata);
const file = new File(
[jsonString],
`agent-${metadata.name}-${Date.now()}.json`,
{ type: 'application/json' }
);
const upload = await this.pinata.upload.public.file(file);
// Return the CID (IPFS hash)
return upload.cid;
} catch (error) {
console.error('IPFS upload error:', error);
throw new Error('Failed to upload metadata to IPFS');
}
}
/**
* Get metadata from IPFS hash (CID)
*/
async getMetadata(cid: string): Promise<any> {
if (!this.pinata) {
throw new Error('Pinata JWT not configured');
}
try {
const data = await this.pinata.gateways.public.get(cid);
return data;
} catch (error) {
console.error('IPFS fetch error:', error);
throw new Error('Failed to fetch metadata from IPFS');
}
}
/**
* Upload file to IPFS
*/
async uploadFile(file: File): Promise<{ cid: string; size: number }> {
if (!this.pinata) {
throw new Error('Pinata JWT not configured');
}
try {
const upload = await this.pinata.upload.public.file(file);
return {
cid: upload.cid,
size: upload.size || file.size,
};
} catch (error) {
console.error('IPFS file upload error:', error);
throw new Error('Failed to upload file to IPFS');
}
}
/**
* Get gateway URL for IPFS hash (CID)
* Uses the configured gateway to construct the URL
*/
getGatewayUrl(cid: string): string {
if (this.gatewayUrl) {
// Remove trailing slash if present, add CID
const base = this.gatewayUrl.endsWith('/')
? this.gatewayUrl.slice(0, -1)
: this.gatewayUrl;
return `${base}/${cid}`;
}
// Fallback to default gateway
return `https://gateway.pinata.cloud/ipfs/${cid}`;
}
}