UNPKG

pipe-protocol

Version:

A protocol for large scale Interplanetary Intertool Agent Context

170 lines 5.85 kB
"use strict"; /** * @file IpfsNode Implementation * @version 1.0.0 * @status STABLE - DO NOT MODIFY WITHOUT TESTS * @lastModified 2024-02-03 * * This file implements a unified IPFS node using Helia with configurable storage backends. * * IMPORTANT: * - This is a STABLE implementation - any modifications require full test coverage * - All changes must maintain backward compatibility * - Changes affecting storage or networking require extensive testing * - Run full test suite before and after modifications * - Document all changes in the version history * * Core Functionality: * - Configurable storage backend (memory or filesystem) * - Network exposure control (enabled/disabled) * - Data addition and retrieval with CID management * - Explicit data export/import for private nodes * - Node lifecycle management (init/cleanup) * - Peer-to-peer communication (when networking enabled) * * Test Coverage Requirements: * - Storage operations (add/get/delete) * - Network isolation verification * - Error handling and recovery * - Resource cleanup * - Cross-node communication * - Data integrity verification */ Object.defineProperty(exports, "__esModule", { value: true }); exports.IpfsNode = void 0; const helia_1 = require("helia"); const libp2p_1 = require("libp2p"); const libp2p_noise_1 = require("@chainsafe/libp2p-noise"); const libp2p_yamux_1 = require("@chainsafe/libp2p-yamux"); const tcp_1 = require("@libp2p/tcp"); const websockets_1 = require("@libp2p/websockets"); const blockstore_core_1 = require("blockstore-core"); const blockstore_fs_1 = require("blockstore-fs"); const identify_1 = require("@libp2p/identify"); const cid_1 = require("multiformats/cid"); const sha2_1 = require("multiformats/hashes/sha2"); const raw = require("multiformats/codecs/raw"); const multiaddr_1 = require("@multiformats/multiaddr"); class IpfsNode { constructor(options) { this.options = options; this.helia = null; this.blockstore = null; this.libp2p = null; } async init() { if (this.helia) { return; // Already initialized } try { const libp2p = await (0, libp2p_1.createLibp2p)({ addresses: { listen: this.options.enableNetworking === false ? [] : ['/ip4/127.0.0.1/tcp/0'] }, transports: this.options.enableNetworking === false ? [] : [(0, tcp_1.tcp)(), (0, websockets_1.webSockets)()], streamMuxers: [(0, libp2p_yamux_1.yamux)()], connectionEncrypters: [(0, libp2p_noise_1.noise)()], services: { identify: (0, identify_1.identify)() } }); const blockstore = this.options.storage === 'memory' ? new blockstore_core_1.MemoryBlockstore() : new blockstore_fs_1.FsBlockstore(this.options.storageConfig?.directory || '/tmp/ipfs'); this.blockstore = blockstore; this.libp2p = libp2p; this.helia = await (0, helia_1.createHelia)({ libp2p, blockstore }); } catch (error) { // Clean up any partially initialized resources await this.stop(); throw error; } } async add(data) { if (!this.helia?.blockstore) { throw new Error('IPFS node not initialized'); } const hash = await sha2_1.sha256.digest(data); const cid = cid_1.CID.createV1(raw.code, hash); await this.helia.blockstore.put(cid, data); await this.pin(cid.toString()); // Auto-pin content when adding return cid.toString(); } async put(data) { return this.add(data); } async get(cidStr) { if (!this.helia?.blockstore) { throw new Error('IPFS node not initialized'); } try { const cid = cid_1.CID.parse(cidStr); return await this.helia.blockstore.get(cid, { signal: AbortSignal.timeout(5000) }); } catch (error) { console.error('Error getting data:', error); return null; } } async pin(cidStr) { if (!this.helia?.pins) { throw new Error('IPFS node not initialized'); } const cid = cid_1.CID.parse(cidStr); await this.helia.pins.add(cid); } async unpin(cidStr) { if (!this.helia?.pins) { throw new Error('IPFS node not initialized'); } const cid = cid_1.CID.parse(cidStr); await this.helia.pins.rm(cid); } async getPinnedCids() { if (!this.helia?.pins) { throw new Error('IPFS node not initialized'); } const pins = []; for await (const pin of this.helia.pins.ls()) { pins.push(pin.toString()); } return pins; } getPeerId() { return this.libp2p?.peerId ?? null; } getMultiaddrs() { if (!this.libp2p) { return []; } return this.libp2p.getMultiaddrs().map(addr => addr.toString()); } async dial(addr) { if (!this.libp2p) { throw new Error('IPFS node not initialized'); } await this.libp2p.dial((0, multiaddr_1.multiaddr)(addr)); } async stop() { if (this.helia) { await this.helia.stop(); this.helia = null; } if (this.blockstore) { if (this.options.storage === 'persistent') { await this.blockstore.close(); } this.blockstore = null; } if (this.libp2p) { await this.libp2p.stop(); this.libp2p = null; } } } exports.IpfsNode = IpfsNode; //# sourceMappingURL=ipfsNode.js.map