{"id":28947902,"url":"https://github.com/scobru/shogun-ipfs","last_synced_at":"2026-05-18T00:09:52.777Z","repository":{"id":294395276,"uuid":"985716477","full_name":"scobru/shogun-ipfs","owner":"scobru","description":"A lightweight wrapper for IPFS storage services that provides a simplified interface for interacting with IPFS networks.","archived":false,"fork":false,"pushed_at":"2026-03-10T17:26:50.000Z","size":82711,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-10T23:08:26.384Z","etag":null,"topics":["client","decetralized","ipfs","ipfs-blockchain","p2p","storage"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/scobru.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-05-18T11:31:29.000Z","updated_at":"2026-03-10T17:26:53.000Z","dependencies_parsed_at":"2025-05-20T08:39:33.097Z","dependency_job_id":"c6ed2358-f929-4b27-9d0e-827cdac4a754","html_url":"https://github.com/scobru/shogun-ipfs","commit_stats":null,"previous_names":["scobru/shogun-ipfs"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/scobru/shogun-ipfs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scobru%2Fshogun-ipfs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scobru%2Fshogun-ipfs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scobru%2Fshogun-ipfs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scobru%2Fshogun-ipfs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/scobru","download_url":"https://codeload.github.com/scobru/shogun-ipfs/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scobru%2Fshogun-ipfs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33160170,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-17T22:39:12.733Z","status":"ssl_error","status_checked_at":"2026-05-17T22:39:10.741Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["client","decetralized","ipfs","ipfs-blockchain","p2p","storage"],"created_at":"2025-06-23T10:02:28.173Z","updated_at":"2026-05-18T00:09:52.771Z","avatar_url":"https://github.com/scobru.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Shogun IPFS 🏓\n\n🌐 **shogun-ipfs** is a lightweight, unified wrapper for IPFS storage services that provides a simplified interface for interacting with IPFS networks.\n\n📦 With support for **multiple storage providers** (Pinata, IPFS Client, Custom Gateways), shogun-ipfs makes it easy to upload, retrieve, and manage content on IPFS without having to deal with the complexities of different API implementations.\n\n🚀 Perfect for developers who need an easy-to-use, reliable way to integrate IPFS storage into their decentralized applications.\n\n## Features\n\n- 🚀 **Simple to Use**: Unified API for all IPFS operations\n- 📦 **Multiple Storage Providers**: Support for Pinata, IPFS nodes, and custom gateways (e.g., Shogun Relay)\n- 🔧 **Buffer Support**: Direct upload of in-memory buffers (perfect for encrypted data)\n- 🛡️ **Robust Error Handling**: Comprehensive error management with automatic retries\n- 🔄 **Rate Limiting**: Built-in protection against API throttling\n- 📝 **Structured Logging**: Detailed operation tracking with Winston\n- 🧩 **Flexible Configuration**: Customizable settings for different environments\n- 🔐 **Auth Support**: Token-based authentication for secured endpoints\n\n## Quick Start\n\n```bash\nyarn add shogun-ipfs\n```\n\nor\n\n```bash\nnpm install shogun-ipfs\n```\n\n```typescript\nimport { ShogunIpfs } from \"shogun-ipfs\";\n\n// Initialize with Pinata (managed IPFS service)\nconst storage = ShogunIpfs({\n  service: \"PINATA\",\n  config: {\n    pinataJwt: process.env.PINATA_JWT || \"\",\n    pinataGateway: \"gateway.pinata.cloud\",\n  },\n});\n\n// Or with IPFS Client (local node)\nconst storage = ShogunIpfs({\n  service: \"IPFS-CLIENT\",\n  config: {\n    url: \"http://localhost:5001\",\n  },\n});\n\n// Or with Custom Gateway (e.g., Shogun Relay)\nconst storage = ShogunIpfs({\n  service: \"CUSTOM\",\n  config: {\n    url: \"https://relay.shogun-eco.xyz/api/v1/ipfs\",\n    token: \"your-admin-token\",\n  },\n});\n\n// Upload JSON data\nconst result = await storage.uploadJson({ name: \"test\", value: \"example data\" });\nconsole.log(\"Content uploaded:\", result.id);\n\n// Upload a file from filesystem\nconst fileResult = await storage.uploadFile(\"./path/to/image.jpg\");\nconsole.log(\"File uploaded:\", fileResult.id);\n\n// Upload a buffer (perfect for encrypted data!)\nconst encryptedBuffer = Buffer.from(\"encrypted-data\");\nconst bufferResult = await storage.uploadBuffer(encryptedBuffer);\nconsole.log(\"Buffer uploaded:\", bufferResult.id);\n\n// Retrieve data\nconst data = await storage.get(result.id);\nconsole.log(\"Retrieved data:\", data.data);\n\n// NEW: Get raw buffer (useful for images, videos, or raw binary)\nconst rawBuffer = await storage.getRaw(result.id);\nconsole.log(\"Raw buffer size:\", rawBuffer.length);\n\n// NEW: Get typed JSON\ninterface MyData {\n  name: string;\n}\nconst jsonData = await storage.getJson\u003cMyData\u003e(result.id);\nconsole.log(\"Retrieved JSON:\", jsonData.name);\n\n// Check if content is pinned\nconst isPinned = await storage.isPinned(result.id);\nconsole.log(\"Is pinned:\", isPinned);\n\n// Unpin when no longer needed\nconst unpinned = await storage.unpin(result.id);\nif (unpinned) {\n  console.log(\"Content unpinned successfully\");\n}\n```\n\n## Storage Providers\n\n`shogun-ipfs` supports three storage providers with automatic endpoint discovery and failover:\n\n### 📌 **PINATA** - Managed IPFS Service\n\nManaged IPFS pinning service with global CDN and automatic replication.\n\n**Best for**: Production apps, public files, guaranteed availability\n\n### 🖥️ **IPFS-CLIENT** - Local/Remote IPFS Node\n\nDirect connection to any IPFS node via HTTP API (Kubo, js-ipfs, etc.)\n\n**Best for**: Self-hosted solutions, private networks, full control\n\n### 🌐 **CUSTOM** - Custom Gateway/Relay\n\nAny IPFS-compatible API endpoint (Shogun Relay, Infura, custom implementations)\n\n**Best for**: Custom infrastructure, relay networks, hybrid setups\n\n### PINATA Configuration\n\n```typescript\nconst storage = ShogunIpfs({\n  service: \"PINATA\",\n  config: {\n    pinataJwt: process.env.PINATA_JWT || \"\",\n    pinataGateway: \"gateway.pinata.cloud\", // Optional\n  },\n});\n```\n\n### IPFS-CLIENT Configuration\n\n```typescript\nconst storage = ShogunIpfs({\n  service: \"IPFS-CLIENT\",\n  config: {\n    url: \"http://localhost:5001\", // Your IPFS node HTTP API endpoint\n    apiKey: \"optional-api-key\", // Optional authentication\n  },\n});\n```\n\n### CUSTOM Gateway Configuration\n\n```typescript\nconst storage = ShogunIpfs({\n  service: \"CUSTOM\",\n  config: {\n    url: \"https://relay.shogun-eco.xyz/api/v1/ipfs\", // Base URL\n    token: \"your-admin-token\", // Optional authentication\n  },\n});\n\n// The service automatically tries multiple endpoints:\n// - /upload (relay format)\n// - /api/v0/add (standard IPFS API)\n// - /add (simplified format)\n```\n\n## Main Operations\n\n### Upload Operations\n\n```typescript\n// Upload JSON data directly\nconst jsonResult = await storage.uploadJson({\n  name: \"test\",\n  data: { key: \"value\" },\n});\nconsole.log(\"JSON uploaded:\", jsonResult.id);\n\n// Upload a buffer (NEW! Perfect for encrypted data)\nconst encryptedData = Buffer.from(\"encrypted-content\");\nconst bufferResult = await storage.uploadBuffer(encryptedData, {\n  filename: \"encrypted-file.bin\", // Optional\n});\nconsole.log(\"Buffer uploaded:\", bufferResult.id);\n\n// Upload a file from filesystem\nconst fileResult = await storage.uploadFile(\"./path/to/file.txt\");\nconsole.log(\"File uploaded:\", fileResult.id);\n```\n\n### Retrieval Operations\n\n```typescript\n// Get data by hash (returns { data, metadata })\n// Now handles both JSON and binary data automatically!\nconst result = await storage.get(\"QmHash...\");\nconsole.log(\"Retrieved data:\", result.data);\nconsole.log(\"Metadata:\", result.metadata);\n\n// Get raw buffer directly (perfect for non-JSON files)\nconst buffer = await storage.getRaw(\"QmHash...\");\nconsole.log(\"Raw size:\", buffer.length);\n\n// Get typed JSON directly\nconst data = await storage.getJson\u003cMyType\u003e(\"QmHash...\");\n\n// Get metadata only\nconst metadata = await storage.getMetadata(\"QmHash...\");\nconsole.log(\"Content metadata:\", metadata);\n\n// Get endpoint URL (useful for constructing links)\nconst endpoint = storage.getEndpoint();\nconsole.log(\"Storage endpoint:\", endpoint);\n```\n\n### Pin Management\n\n```typescript\n// Check if content is pinned\nconst isPinned = await storage.isPinned(\"QmHash...\");\nconsole.log(\"Is content pinned?\", isPinned);\n\n// Unpin content\nconst unpinned = await storage.unpin(\"QmHash...\");\nif (unpinned) {\n  console.log(\"Content unpinned successfully\");\n} else {\n  console.log(\"Content not found or already unpinned\");\n}\n```\n\n## Error Handling\n\nshogun-ipfs implements comprehensive error handling with automatic retries for Custom Gateway:\n\n```typescript\ntry {\n  const result = await storage.uploadFile(\"./path/to/file.txt\");\n  console.log(\"Uploaded to:\", result.id);\n} catch (error) {\n  if (error.message.includes(\"INVALID_CREDENTIALS\")) {\n    console.error(\"Authentication failed. Check your JWT token.\");\n  } else if (error.message.includes(\"NOT_FOUND\")) {\n    console.error(\"File not found or not accessible.\");\n  } else if (error.message.includes(\"All upload endpoints failed\")) {\n    console.error(\"Custom gateway unreachable. Check URL and network.\");\n  } else {\n    console.error(\"Upload failed:\", error.message);\n  }\n}\n```\n\n## Advanced Usage\n\n### Using with SHIP-05 (Shogun Decentralized Storage)\n\n```typescript\nimport { ShogunIpfs } from \"shogun-ipfs\";\n\n// Configure for Shogun Relay\nconst ipfsStorage = ShogunIpfs({\n  service: \"CUSTOM\",\n  config: {\n    url: \"https://relay.shogun-eco.xyz/api/v1/ipfs\",\n    token: process.env.ADMIN_TOKEN,\n  },\n});\n\n// Encrypt data with SEA, then upload\nconst encryptedData = await SEA.encrypt(fileData, userKey);\nconst encryptedBuffer = Buffer.from(encryptedData);\n\nconst result = await ipfsStorage.uploadBuffer(encryptedBuffer, {\n  filename: \"encrypted-file.bin\",\n});\n\nconsole.log(\"Encrypted file uploaded:\", result.id);\n\n// Download and decrypt\nconst downloaded = await ipfsStorage.get(result.id);\nconst decrypted = await SEA.decrypt(downloaded.data, userKey);\n```\n\n### Endpoint Auto-Discovery (Custom Gateway)\n\nWhen using `CUSTOM` service, shogun-ipfs automatically tries multiple endpoints:\n\n**Upload attempts** (in order):\n\n1. `/upload` - Relay format (Shogun Relay, custom implementations)\n2. `/api/v0/add` - Standard IPFS API\n3. `/add` - Simplified format\n\n**Download attempts** (in order):\n\n1. `/content/{hash}` - Relay format with metadata\n2. `/ipfs/{hash}` - Standard gateway format\n3. `/api/v0/cat?arg={hash}` - IPFS API format\n\nThis ensures compatibility with virtually any IPFS-compatible endpoint!\n\n## API Reference\n\n### StorageService Interface\n\nAll storage providers implement the same interface:\n\n```typescript\ninterface StorageService {\n  // Upload operations\n  uploadJson(jsonData: Record\u003cstring, unknown\u003e, options?: any): Promise\u003cUploadOutput\u003e;\n  uploadFile(filePath: string, options?: any): Promise\u003cUploadOutput\u003e;\n  uploadBuffer(buffer: Buffer, options?: any): Promise\u003cUploadOutput\u003e;\n\n  // Download operations\n  get(hash: string): Promise\u003c{ data: any; metadata: any }\u003e;\n  getRaw(hash: string): Promise\u003cBuffer\u003e;\n  getJson\u003cT\u003e(hash: string): Promise\u003cT\u003e;\n  getMetadata(hash: string): Promise\u003cany\u003e;\n\n  // Pin management\n  isPinned(hash: string): Promise\u003cboolean\u003e;\n  unpin(hash: string): Promise\u003cboolean\u003e;\n\n  // Utility\n  getEndpoint?(): string;\n}\n```\n\n### UploadOutput\n\n```typescript\ninterface UploadOutput {\n  id: string; // IPFS hash (CID)\n  url?: string; // Optional URL to access the content\n  metadata?: Record\u003cstring, any\u003e; // Additional metadata (timestamp, size, etc.)\n}\n```\n\n## Best Practices\n\n1. **Choose the Right Provider**\n   - **Pinata**: For production apps with guaranteed uptime\n   - **IPFS-CLIENT**: For self-hosted solutions and local development\n   - **CUSTOM**: For relay networks and custom infrastructure\n\n2. **Rate Limiting Awareness**\n   - Built-in rate limiting protects against API throttling\n   - Pinata: 2 req/sec, IPFS-CLIENT: 5 req/sec, CUSTOM: 10 req/sec\n\n3. **Error Handling**\n   - Always wrap operations in try/catch blocks\n   - Custom Gateway automatically retries failed endpoints\n\n4. **Content Management**\n   - Regularly unpin content that is no longer needed\n   - Monitor pinned content size with paid services\n   - Use `isPinned()` before `unpin()` for efficiency\n\n5. **Buffer Uploads for Encrypted Data**\n   - Use `uploadBuffer()` for in-memory encrypted data\n   - Avoids creating temporary files\n   - Better performance for SHIP-05 encrypted storage\n\n## Development\n\n```bash\n# Install dependencies\nyarn install\n\n# Run tests\nyarn test\n\n# Build\nyarn build\n```\n\n## License\n\nMIT License\n\nCopyright (c) 2024 scobru\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscobru%2Fshogun-ipfs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fscobru%2Fshogun-ipfs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscobru%2Fshogun-ipfs/lists"}