{"id":14956236,"url":"https://github.com/alexbakers/ipfs-storage","last_synced_at":"2026-01-20T18:56:04.806Z","repository":{"id":61388653,"uuid":"551194166","full_name":"alexbakers/ipfs-storage","owner":"alexbakers","description":"IPFS storage API providers.","archived":false,"fork":false,"pushed_at":"2023-01-21T16:09:55.000Z","size":73,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-14T22:39:14.446Z","etag":null,"topics":["filebase","fleek","ipfs","ipfs-api","ipfs-protocol","ipfs-web","lighthouse","pinata","storage","web3","web3storage"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/ipfs-storage","language":"JavaScript","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/alexbakers.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-10-14T01:35:47.000Z","updated_at":"2023-08-24T13:29:55.000Z","dependencies_parsed_at":"2023-02-12T11:10:14.245Z","dependency_job_id":null,"html_url":"https://github.com/alexbakers/ipfs-storage","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexbakers%2Fipfs-storage","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexbakers%2Fipfs-storage/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexbakers%2Fipfs-storage/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexbakers%2Fipfs-storage/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alexbakers","download_url":"https://codeload.github.com/alexbakers/ipfs-storage/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247644945,"owners_count":20972381,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["filebase","fleek","ipfs","ipfs-api","ipfs-protocol","ipfs-web","lighthouse","pinata","storage","web3","web3storage"],"created_at":"2024-09-24T13:12:34.779Z","updated_at":"2026-01-20T18:56:04.792Z","avatar_url":"https://github.com/alexbakers.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# IPFS STORAGE API PROVIDERS\n\n\u003cimg alt=\"IPFS STORAGE API PROVIDERS\" src=\"https://raw.githubusercontent.com/alexbakers/ipfs-storage/main/banner.png\" /\u003e\n\nThis library provides a unified interface for uploading files to and deleting files from various IPFS storage providers.\n\n**Supported Providers:**\n\n- [x] Filebase [\u003ca href=\"https://filebase.com\"\u003efilebase.com\u003c/a\u003e]\n- [x] Storacha [\u003ca href=\"https://storacha.network\"\u003estoracha.network\u003c/a\u003e] (formerly web3.storage)\n- [x] Pinata [\u003ca href=\"https://pinata.cloud\"\u003epinata.cloud\u003c/a\u003e]\n- [x] Lighthouse [\u003ca href=\"https://lighthouse.storage\"\u003elighthouse.storage\u003c/a\u003e]\n- [ ] **Fleek [\u003ca href=\"https://fleek.xyz\"\u003efleek.xyz\u003c/a\u003e] (Temporarily Disabled)**\n\n## Prerequisites\n\n- **Node.js:** Version 18 or higher.\n- **Credentials:** You will need API credentials for each service you intend to use. Store these securely, for example, using environment variables (see examples).\n- **Storacha Setup:** Storacha requires a one-time setup using their CLI (`w3`) to log in your agent (`w3 login \u003cemail\u003e`) and create/select a space (`w3 space create`, `w3 space use`). This library assumes the agent is already configured in the environment where the code runs.\n\n## Installation\n\n```bash\nnpm install ipfs-storage\n# or\nyarn add ipfs-storage\n```\n\n## Breaking Changes (v1.x -\u003e v2.x)\n\n- **Pinata:** `uploadFile.pinata` now returns an object `{ url: string, providerId: string }`. The `providerId` is required for `deleteFile.pinata`.\n- **Fleek:** Authentication changed (requires PAT/ProjectID), but the provider is **temporarily disabled** due to module resolution issues with `@fleek-platform/sdk` in ESM projects.\n- **Storacha (web3.storage):** Authentication requires a pre-configured agent (via `w3 login`) instead of an API token.\n- **Dependencies:** Underlying SDKs for all providers have been updated.\n\n## Examples\n\nFirst, set up your environment variables (e.g., in a `.env` file and load with `dotenv`):\n\n```.env\n# Filebase\nFILEBASE_KEY=YOUR_FILEBASE_ACCESS_KEY\nFILEBASE_SECRET=YOUR_FILEBASE_SECRET_KEY\nFILEBASE_BUCKET=your-filebase-bucket-name\n\n# Pinata\nPINATA_JWT=YOUR_PINATA_JWT\n\n# Storacha (No key needed here, login via w3 cli)\n```\n\nThen, use the library in your code:\n\n```javascript\nconst fs = require(\"fs\");\nconst { join } = require(\"path\");\nconst { uploadFile, deleteFile } = require(\"ipfs-storage\");\nconst { create } = require('@web3-storage/w3up-client'); // Needed for pre-configured client example\nrequire(\"dotenv\").config(); // Load .env variables\n\n// Helper function to extract CID v1 from common IPFS gateway URLs\nconst extractCidFromUrl = (url) =\u003e {\n  try {\n    const urlObject = new URL(url);\n    const hostnameParts = urlObject.hostname.split(\".\");\n    // Assuming format like https://{cid}.ipfs.{gateway}/\n    if (hostnameParts.length \u003e 2 \u0026\u0026 hostnameParts[1] === \"ipfs\") {\n      return hostnameParts[0];\n    }\n  } catch (e) { /* ignore */ }\n  return null;\n};\n\n// Example usage (run within an async function or use .then())\nasync function runExamples() {\n  let fileBuffer;\n  try {\n    fileBuffer = fs.readFileSync(join(__dirname, \"banner.png\"));\n  } catch (err) {\n    console.error(\"Error reading file:\", err);\n    return;\n  }\n\n  const fileData = { hash: \"banner-test\", ext: \".png\", buffer: fileBuffer };\n\n  // --- Filebase Example ---\n  if (process.env.FILEBASE_KEY) {\n    try {\n      const filebaseConnect = {\n        key: process.env.FILEBASE_KEY,\n        secret: process.env.FILEBASE_SECRET,\n        bucket: process.env.FILEBASE_BUCKET,\n      };\n      const url = await uploadFile.filebase(filebaseConnect, fileData);\n      console.log(\"✅ FILEBASE Upload:\", url);\n\n      await deleteFile.filebase(filebaseConnect, { hash: fileData.hash, ext: fileData.ext });\n      console.log(\"✅ FILEBASE Delete: OK\");\n    } catch (err) {\n      console.error(\"🆘 FILEBASE:\", err.message || err);\n    }\n  }\n\n  // --- Pinata Example ---\n  if (process.env.PINATA_JWT) {\n    try {\n      const pinataConnect = { jwt: process.env.PINATA_JWT };\n      // Pinata upload now returns { url, providerId }\n      const result = await uploadFile.pinata(pinataConnect, fileData);\n      console.log(\"✅ PINATA Upload:\", result.url);\n\n      // Pinata delete now requires the providerId\n      await deleteFile.pinata(pinataConnect, { providerId: result.providerId });\n      console.log(\"✅ PINATA Delete: OK\");\n    } catch (err) {\n      console.error(\"🆘 PINATA:\", err.message || err);\n    }\n  }\n\n  // --- Fleek Example ---\n  /* // Temporarily disabled due to SDK compatibility issues\n  if (process.env.FLEEK_PAT \u0026\u0026 process.env.FLEEK_PROJECT_ID) {\n  // ... (Fleek example code commented out) ...\n  }\n  */\n\n  // --- Storacha Example (formerly Web3.storage) ---\n  console.log(\"\\n--- Storacha ---\");\n\n  // Storacha requires a one-time EXTERNAL setup using `w3 login \u003cemail\u003e`\n  // and `w3 space use \u003cdid\u003e` before this library can use the ambient state.\n  // The library CANNOT perform the interactive email login.\n  console.log(\"Attempting Storacha using ambient agent state...\");\n  try {\n    // If agent is logged in and space is set externally, this will work:\n    const url = await uploadFile.storacha({}, fileData);\n    console.log(\"✅ STORACHA Upload (Ambient):\", url);\n    const cid = extractCidFromUrl(url);\n    if (cid) {\n      await deleteFile.storacha({}, { cid });\n      console.log(\"✅ STORACHA Delete (Ambient): OK\");\n    } else {\n      console.error(\"🆘 STORACHA Delete (Ambient): Could not extract CID from URL\", url);\n    }\n  } catch (err) {\n    console.warn(\"🆘 STORACHA (Ambient State):\", err.message || err, \"(FAILED: Ensure agent is logged in and space is selected externally via w3 commands)\");\n  }\n\n  // Option for applications: Pass a pre-configured client \u0026 space DID\n  // (Application must handle client creation, login flow, and space selection itself)\n  console.log(\"\\nExample: Using Storacha with a pre-configured client (if available)... \");\n  let preConfiguredClient;\n  let spaceDidToUse; // Replace with your actual Space DID\n  try {\n    // Example: Initialize client (in a real app, handle login flow properly)\n    preConfiguredClient = await create();\n    const accounts = await preConfiguredClient.accounts();\n    if (!accounts || Object.keys(accounts).length === 0) {\n      console.warn(\"  -\u003e Storacha Pre-config: Agent not logged in. Skipping pre-configured client test.\");\n      // In a real app: initiate login -\u003e await client.login('email'); ... wait for link click ...\n    } else {\n      const spaces = await preConfiguredClient.spaces();\n      if (!spaces || spaces.length === 0) {\n         console.warn(\"  -\u003e Storacha Pre-config: Agent has no spaces. Skipping pre-configured client test.\");\n      } else {\n         spaceDidToUse = spaces[0].did(); // Using the first space for the example\n         console.log(`  -\u003e Storacha Pre-config: Using space DID: ${spaceDidToUse}`);\n\n         const storachaConnect = { client: preConfiguredClient, spaceDid: spaceDidToUse };\n         const url = await uploadFile.storacha(storachaConnect, fileData);\n         console.log(\"✅ STORACHA Upload (Pre-config):\", url);\n         const cid = extractCidFromUrl(url);\n         if (cid) {\n           await deleteFile.storacha(storachaConnect, { cid });\n           console.log(\"✅ STORACHA Delete (Pre-config): OK\");\n         } else {\n           console.error(\"🆘 STORACHA Delete (Pre-config): Could not extract CID from URL\", url);\n         }\n      }\n    }\n  } catch (err) {\n     console.error(\"🆘 STORACHA (Pre-configured Client Example):\", err.message || err);\n  }\n\n  // --- Lighthouse Example ---\n  if (process.env.LIGHTHOUSE_TOKEN) {\n    try {\n      const lighthouseConnect = { token: process.env.LIGHTHOUSE_TOKEN };\n      const url = await uploadFile.lighthouse(lighthouseConnect, fileData);\n      console.log(\"✅ LIGHTHOUSE Upload:\", url);\n\n      // Note: deleteFile.lighthouse is currently not implemented (pending SDK docs)\n      const cid = extractCidFromUrl(url);\n      if (cid) {\n        try {\n          await deleteFile.lighthouse(lighthouseConnect, { cid });\n          console.log(\"✅ LIGHTHOUSE Delete: OK (Unimplemented function did not throw?)\");\n        } catch (deleteErr) {\n          if (deleteErr.message \u0026\u0026 deleteErr.message.includes(\"not implemented\")) {\n            console.log(\"✅ LIGHTHOUSE Delete: OK (Not implemented as expected)\");\n          } else {\n            console.error(\"🆘 LIGHTHOUSE Delete Error:\", deleteErr.message || deleteErr);\n          }\n        }\n      } else {\n        console.error(\"🆘 LIGHTHOUSE Delete: Could not extract CID from URL\", url);\n      }\n    } catch (err) {\n      console.error(\"🆘 LIGHTHOUSE:\", err.message || err);\n    }\n  }\n}\n\nrunExamples();\n\n---\n\n`(c)` Alex Baker\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexbakers%2Fipfs-storage","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexbakers%2Fipfs-storage","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexbakers%2Fipfs-storage/lists"}