ipfs-file-pin-service

May 29, 2026 · View on GitHub

js-standard-style semantic-release

ipfs-file-pin-service is part of the optional IPFS layer in the Cash Stack.

ipfs-file-pin-service dependency graph

This project runs a Helia IPFS node and REST API server that provides paid IPFS file pinning using the PSF File Pinning Protocol (PS010). This code base was forked from ipfs-service-provider.

The service is activated by psf-slp-indexer-g2, via a webhook when it detects a new Pin Claim on the blockchain. It depends on psf-bch-api to interact with the BCH blockchain. When a new Pin Claim is detected on the blockchain, the service:

  1. Validates that a proper proof-of-burn of PSF tokens was submitted with the claim.
  2. Verifies that the burn amount meets the required cost based on file size.
  3. Downloads the IPFS content and pins it to the local Helia node.
  4. Serves the pinned content via HTTP download and view endpoints.

Features

  • Blockchain-Validated Pinning -- Processes Pin Claims from the Bitcoin Cash blockchain and validates proof-of-burn transactions against the PSF token write price set by the PSF Minting Council.
  • Embedded Helia IPFS Node -- Runs a full Helia IPFS node with TCP, WebSocket, and optional WebRTC transports. Supports circuit relay for nodes behind NATs/firewalls.
  • Dual API Interface -- Exposes both a REST API over HTTP and a JSON-RPC API over IPFS for decentralized access.
  • File Downloads and Viewing -- Serves pinned content via HTTP endpoints for direct file download and in-browser viewing.
  • Automatic Retry Queue -- Failed downloads are retried with a concurrent queue (up to 20 parallel downloads, 5-minute timeout per attempt).
  • Pin Renewals -- Supports renewing pins with additional proof-of-burn transactions.
  • Dynamic Pricing -- Fetches the current write price from the PSF Minting Council so pin costs stay in sync with token valuation.
  • User Management -- Built-in user authentication with JWT tokens and Passport.js.
  • Periodic Maintenance -- Timer-based controllers handle pin processing (every 10 minutes), usage cleanup (every hour), and automatic restarts (every 6 hours).

Requirements

  • Node.js ^20.16.0
  • npm ^10.8.1
  • MongoDB 4.2+
  • Docker ^24.0.7 (production deployment)
  • Docker Compose ^1.27.4 (production deployment)

Installation

Production Environment (Docker)

The recommended way to run in production is with Docker Compose. The production/docker directory contains the Dockerfile and Compose configuration.

cd production/docker
docker compose up -d

This starts two containers:

ContainerDescriptionPorts
mongo-file-serviceMongoDB 4.2 database5556 -> 27017
file-serviceApplication server5031 (REST), 4001 (TCP), 4003 (WS), 4005 (WebRTC)
  • Bring containers down: docker compose down
  • Bring containers back up: docker compose up -d
  • View logs: docker compose logs -f file-service

Production environment variables are set in production/docker/start-production.sh. Edit this file to configure your deployment before starting containers.

Development Environment

git clone https://github.com/Permissionless-Software-Foundation/ipfs-file-pin-service
cd ipfs-file-pin-service
./install-mongo.sh
npm install
npm start

The development server starts on port 5031 by default and connects to a local MongoDB instance at mongodb://localhost:27017/ipfs-file-pin-dev.

Configuration

The application is configured through environment variables. All configuration is centralized in config/env/common.js, with environment-specific overrides in the config/env/ directory.

Server

VariableDescriptionDefault
PORTREST API port5031
SVC_ENVEnvironment: development, test, or proddevelopment
NO_MONGODisable MongoDB (set to any value to enable)unset (MongoDB enabled)
ADMIN_PASSWORDAdmin account passwordunset
DISABLE_NEW_ACCOUNTSDisable new user account creationunset (accounts enabled)

IPFS Node

VariableDescriptionDefault
DISABLE_IPFSDisable the IPFS node at startup (set to any value to disable)unset (IPFS enabled)
COORD_NAMEHuman-readable name for the IPFS nodeipfs-bch-wallet-service
DEBUG_LEVELhelia-coord debug verbosity (0=none, 3=max)2
IPFS_TCP_PORTIPFS TCP transport port4001
IPFS_WS_PORTIPFS WebSocket transport port4003
IPFS_WEB_RTC_PORTIPFS WebRTC transport port4005
CONNECT_PREFConnection preference: cr (circuit relay) or directcr
ENABLE_CIRCUIT_RELAYEnable circuit relay mode (node must not be behind a firewall)unset (disabled)
CR_DOMAINSSL domain for WebSocket circuit relay connectionsunset
USE_WEB_RTCEnable WebRTC transportfalse
IPFS_HOSTExternal IPFS host (production)localhost
IPFS_API_PORTExternal IPFS API port (production)5001
WEB2_APIPublic REST API URL announced to IPFS peersunset
STARTUP_PEERSComma-separated IPFS multiaddrs to dial after Helia startupunset (none)

After the Helia node starts, the service dials each address in STARTUP_PEERS. Use this to connect to specific peers on your private network (for example, other pin service nodes or indexers). A failed dial is logged as a warning and does not prevent the server from starting.

export STARTUP_PEERS="/ip4/78.46.129.7/tcp/4001/p2p/12D3KooWEBzgK8a5TpMfLotuj7jJnEK41gbD9LZK6qCpxNrX43E9,/ip4/5.78.70.29/tcp/4001/p2p/12D3KooWSREJ6x2DJSYrA1xRD2Qs6D4DHncsHmNnTHuMKHnqpG2i"

Each value must be a full multiaddr including the /p2p/<peer-id> component. This is separate from the default PSF bootstrap peers configured inside helia-coord; STARTUP_PEERS adds explicit connections on top of normal network discovery.

You can also connect to peers at runtime via POST /ipfs/connect.

Wallet

VariableDescriptionDefault
MNEMONIC12-word BCH mnemonic for encryption keys and payment addressempty (required for production)
WALLET_FILEPath to a wallet file generated by psf-bch-wallet./wallet.json
WALLET_INTERFACEWallet connection mode: web3 (IPFS JSON-RPC) or web2 (HTTP REST)web3
APISERVERBCH API server URL (used with web2 interface)https://api.fullstack.cash/v5/
WALLET_AUTH_PASSBasic auth password for the web2 APIempty

File Pinning

VariableDescriptionDefault
MAX_PIN_SIZEMaximum allowable file size in bytes100000000 (100 MB)
REQ_TOKEN_QTYDefault PSF tokens required per MB (overridden by Minting Council lookup)0.03570889
DOMAIN_NAMEBase URL for file download linkshttp://localhost:5031

Email (optional)

VariableDescriptionDefault
EMAILSERVERSMTP servermail.someserver.com
EMAILUSEREmail usernamenoreply@someserver.com
EMAILPASSEmail passwordempty

Database (per environment)

EnvironmentConnection String
Developmentmongodb://localhost:27017/ipfs-file-pin-dev
Testmongodb://localhost:27017/ipfs-file-pin-test
Productionmongodb://172.17.0.1:5555/ipfs-file-pin-prod (or override with DBURL)

REST API Endpoints

The REST API is served on the configured PORT (default 5031). Generated API documentation is available at the root URL after running npm run docs.

IPFS (/ipfs)

MethodEndpointDescription
GET/ipfsGet IPFS node status
POST/ipfs/peersList connected peers
POST/ipfs/relaysList circuit relay connections
POST/ipfs/connectConnect to a specific peer
POST/ipfs/pin-claimSubmit a pin claim (webhook endpoint)
GET/ipfs/pin-status/:cidGet pin status for a CID
GET/ipfs/pins/:pageList pins (paginated, 20 per page)
GET/ipfs/unprocessed-pinsList unprocessed pin claims
POST/ipfs/pin-local-fileUpload and pin a file via HTTP
GET/ipfs/download/:cid/:name?Download a pinned file
GET/ipfs/view/:cid/:name?View a pinned file in the browser
GET/ipfs/download-cid/:cidDownload any CID from the IPFS network
GET/ipfs/nodeGet this node's IPFS identity

Auth (/auth)

MethodEndpointDescription
POST/auth/loginUser login
POST/auth/logoutUser logout

Users (/users)

MethodEndpointDescription
POST/usersCreate user
GET/users/:idGet user
PUT/users/:idUpdate user
DELETE/users/:idDelete user

Other

MethodEndpointDescription
POST/contactSend a contact message via email
GET/logsView application logs (password protected)
GET/usageGet usage statistics

JSON-RPC API (over IPFS)

In addition to the REST API, the service exposes a JSON-RPC interface over IPFS using helia-coord. This allows decentralized access without a direct HTTP connection. Available RPC methods include pinClaim, getFileMetadata, getPins, users, auth, and about.

psf-bch-wallet is a CLI tool that can interact with this JSON-RPC API.

File Structure

This repository follows Clean Architecture principles:

src/
├── adapters/          # Interfaces to external services (IPFS, MongoDB, wallet)
│   ├── ipfs/          # Helia IPFS node adapter
│   ├── localdb/       # Mongoose models and database adapter
│   └── wallet.adapter.js
├── controllers/       # Input handlers
│   ├── rest-api/      # Koa REST API routes and middleware
│   ├── json-rpc/      # JSON-RPC handlers (over IPFS)
│   └── timer-controllers.js  # Periodic tasks (pin processing, cleanup)
├── entities/          # Business logic validation
└── use-cases/         # Application business rules

Usage

CommandDescription
npm startStart the server
npm testRun unit tests
npm run test:allRun unit and e2e tests
npm run test:e2e:autoRun e2e tests only
npm run lintLint code with Standard.js
npm run docsGenerate API documentation
npm run coverage:reportGenerate HTML coverage report

Documentation

API documentation is written inline and generated by apidoc:

npm run docs

Then visit http://localhost:5020/ to view the generated docs.

There is additional developer documentation in the dev-docs directory.

License

MIT