UNPKG

filecoin-pin

Version:

Bridge IPFS content to Filecoin Onchain Cloud using familiar tools

102 lines (89 loc) 3.07 kB
import { noise } from '@chainsafe/libp2p-noise' import { yamux } from '@chainsafe/libp2p-yamux' import { bitswap } from '@helia/block-brokers' import { identify } from '@libp2p/identify' import { tcp } from '@libp2p/tcp' import { multiaddr } from '@multiformats/multiaddr' import { MemoryDatastore } from 'datastore-core' import { createHelia, type Helia } from 'helia' import { createLibp2p } from 'libp2p' import type { CID } from 'multiformats/cid' import type { Logger } from 'pino' import { CARWritingBlockstore } from './core/car/index.js' import type { Config } from './core/synapse/index.js' export interface PinningHeliaOptions { config: Config logger: Logger rootCID: CID outputPath: string origins?: string[] // Multiaddrs to connect to for content } /** * Create a Helia node with CAR-writing blockstore for a specific pin operation * This combines the server and CAR Helia functionality into one instance */ export async function createPinningHeliaNode(options: PinningHeliaOptions): Promise<{ helia: Helia blockstore: CARWritingBlockstore }> { const { logger, rootCID, outputPath, origins = [] } = options // Parse origins into multiaddrs const dialTargets = origins .map((origin) => { try { return multiaddr(origin) } catch (error) { logger.warn({ origin, error }, 'Failed to parse origin multiaddr') return null } }) .filter((addr) => addr != null) const libp2p = await createLibp2p({ addresses: { listen: ['/ip4/0.0.0.0/tcp/0'], // Random port }, transports: [tcp()], connectionEncrypters: [noise()], streamMuxers: [yamux()], services: { identify: identify(), }, // No bootstrap or mdns - we'll connect directly to origins }) // Create CAR-writing blockstore const carBlockstore = new CARWritingBlockstore({ rootCID, outputPath, logger, }) // Set up event handlers for monitoring carBlockstore.on('block:stored', (data) => { logger.debug({ cid: data.cid.toString(), size: data.size }, 'Block stored to CAR file') }) carBlockstore.on('block:missing', (data) => { logger.warn({ cid: data.cid.toString() }, 'Block not found during fetch') }) const helia = await createHelia({ libp2p, blockstore: carBlockstore, datastore: new MemoryDatastore(), blockBrokers: [bitswap()], }) logger.info(`Pinning Helia node started with peer ID: ${helia.libp2p.peerId.toString()}`) logger.info(`Writing blocks to CAR file: ${outputPath}`) // Connect to origin nodes if provided if (dialTargets.length > 0) { logger.info({ origins: dialTargets.length }, 'Connecting to origin nodes') for (const addr of dialTargets) { try { if (addr != null) { await helia.libp2p.dial(addr) logger.info({ addr: addr.toString() }, 'Connected to origin node') } } catch (error) { logger.warn({ addr: addr?.toString(), error }, 'Failed to connect to origin node') } } } return { helia, blockstore: carBlockstore } }