{"id":20975222,"url":"https://github.com/functionland/pinning-service","last_synced_at":"2026-01-05T05:04:37.613Z","repository":{"id":246560755,"uuid":"819632061","full_name":"functionland/pinning-service","owner":"functionland","description":"This is the pinning service","archived":false,"fork":false,"pushed_at":"2025-01-02T01:34:04.000Z","size":105428,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-01-20T05:43:10.540Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","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/functionland.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}},"created_at":"2024-06-24T22:49:18.000Z","updated_at":"2025-01-02T01:34:07.000Z","dependencies_parsed_at":"2025-01-02T02:53:36.749Z","dependency_job_id":null,"html_url":"https://github.com/functionland/pinning-service","commit_stats":null,"previous_names":["functionland/pinning-service"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/functionland%2Fpinning-service","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/functionland%2Fpinning-service/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/functionland%2Fpinning-service/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/functionland%2Fpinning-service/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/functionland","download_url":"https://codeload.github.com/functionland/pinning-service/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243374326,"owners_count":20280661,"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":[],"created_at":"2024-11-19T04:41:08.959Z","updated_at":"2026-01-05T05:04:37.607Z","avatar_url":"https://github.com/functionland.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# IPFS Pinning Service\n\nThis is the repository for the IPFS Pinning Service API that runs at https://api1.cloud.fx.land. The requests are distributed through https://api.cloud.fx.land which runs the code inside `pool-server`.\n\n## Features\n\n- **SQLite Backend**: Fast, lightweight local database with WAL mode for optimal concurrency\n- **IPFS Pinning API Compliant**: Follows the [IPFS Pinning Service API Specification](https://ipfs.github.io/pinning-services-api-spec/)\n- **Production Ready**: Comprehensive error handling, input validation, and graceful shutdown\n- **Low Resource Usage**: Optimized for minimal memory footprint\n\n## Requirements\n\n- Go 1.22+\n- IPFS node (Kubo) running locally\n- IPFS Cluster (optional, for distributed pinning)\n\n## Quick Installation\n\n### Automated Installation (Recommended)\n\nRun the installation script as root:\n\n```bash\nsudo ./install.sh\n```\n\nThe script will:\n1. Prompt for configuration values (with defaults from existing `.env` if upgrading)\n2. Build the application\n3. Create the systemd service\n4. Start the service\n\nDefault installation directory: `/home/root/pinning-service`\n\n### Manual Installation\n\n1. **Build the application:**\n```bash\ngo build -o ./ipfs-pinning main_sqlite.go\n```\n\n2. **Create configuration file:**\n```bash\ncp .env.example .env\n# Edit .env with your configuration\n```\n\n3. **Create data directory:**\n```bash\nmkdir -p data\n```\n\n4. **Copy service file:**\n```bash\nsudo cp ipfs-server/fula-pinning-service.service /etc/systemd/system/\n```\n\n5. **Enable and start service:**\n```bash\nsudo systemctl daemon-reload\nsudo systemctl enable fula-pinning-service\nsudo systemctl start fula-pinning-service\n```\n\n## Configuration\n\nEdit `.env` file with your settings:\n\n```env\n# Server Configuration\nPORT=6000\n\n# Database Configuration (SQLite)\nDATABASE_PATH=data/pinning.db\n\n# IPFS Configuration\nIPFS_API_ADDR=/ip4/127.0.0.1/tcp/5001\n\n# Blockchain Configuration\nBLOCKCHAIN_API_ENDPOINT=http://your-blockchain-api\nMASTER_SEED=your_master_seed\nPOOL_SEED=your_pool_seed\nPOOL_ID=1\n```\n\n## Database Schema\n\nThe SQLite database includes the following optimized tables:\n\n- **users**: User accounts with password hashes and pool assignments\n- **sessions**: Active user sessions for authentication\n- **pins**: Pin records with CID, metadata, and status tracking\n- **logins**: Audit log for login attempts (security monitoring)\n\nAll tables have appropriate indexes for fast queries.\n\n## API Endpoints\n\n### Pins API (IPFS Standard)\n- `POST /pins` - Add a new pin\n- `GET /pins` - List pins with filtering\n- `GET /pins/{requestid}` - Get pin by request ID\n- `POST /pins/{requestid}` - Replace a pin\n- `DELETE /pins/{requestid}` - Delete a pin\n\n### Authentication API\n- `POST /auth/register` - Register new user\n- `POST /auth/login` - Login and get session token\n- `POST /auth/logout` - Logout and invalidate session\n\n### Admin API (System-Only)\n\nThese endpoints require `X-System-Key` header or `Authorization: Bearer \u003cSYSTEM_KEY\u003e` for authentication.\n\n#### Get Pending Pins\n```\nGET /admin/pins/pending?after=2024-01-01T00:00:00Z\u0026before=2024-12-31T23:59:59Z\u0026username=user@example.com\u0026limit=200\u0026status=pending\n```\n| Parameter | Required | Default | Description |\n|-----------|----------|---------|-------------|\n| `after` | Yes | - | Start time filter (RFC3339) |\n| `before` | No | - | End time filter (RFC3339) |\n| `username` | No | - | Filter by username |\n| `limit` | No | 200 | Max results (1-1000) |\n| `status` | No | pending | Status filter: `pending`, `queued`, `pinning`, `pinned`, `failed` |\n\n#### Batch Update Pin Status\n```\nPOST /admin/pins/status\nContent-Type: application/json\n\n{\n  \"updates\": [\n    {\"cid\": \"Qm...\", \"status\": \"pinned\"},\n    {\"cid\": \"Qm...\", \"upload_status\": \"uploaded\"}\n  ]\n}\n```\n\n#### Batch Update Pin Size\n```\nPOST /admin/pins/size\nContent-Type: application/json\n\n{\n  \"updates\": [\n    {\"cid\": \"Qm...\", \"size\": 12345678}\n  ]\n}\n```\n\n#### Get System Stats\n```\nGET /admin/stats\n```\n\n#### Get Storage by User\nReturns total storage used by a user across all their sessions/API keys.\n```\nGET /admin/storage/user/{username}\n```\nResponse includes session breakdown showing storage per API key.\n\n#### Get Storage by Session (API Key)\nReturns storage used by a specific session token.\n```\nGET /admin/storage/session/{token}\n```\n\n#### Get Total Storage Stats\n```\nGET /admin/storage\n```\n\n## Service Management\n\n```bash\n# View service status\nsudo systemctl status fula-pinning-service\n\n# View logs\nsudo journalctl -u fula-pinning-service -f\n\n# Restart service\nsudo systemctl restart fula-pinning-service\n\n# Stop service\nsudo systemctl stop fula-pinning-service\n```\n\n## Development\n\n### Running Unit Tests\n```bash\ncd openapi/go\ngo test -v ./...\n```\n\n### Running Benchmarks\n```bash\ncd openapi/go\ngo test -bench=. -benchmem ./...\n```\n\n### Running IPFS Pinning Service Compliance Tests\n\nThe service supports a **test mode** for running the official IPFS Pinning Service compliance tests.\n\n**Prerequisites:**\n- IPFS daemon running locally (`ipfs daemon`)\n- Node.js installed (for npx)\n\n**Step 1: Start the service in test mode**\n\nWindows (PowerShell):\n```powershell\n.\\run-test-mode.ps1\n```\n\nLinux/Mac:\n```bash\n./run-test-mode.sh\n```\n\nOr manually:\n```bash\nTEST_MODE=true go run main_sqlite.go\n```\n\n**Step 2: Run the compliance tests (in another terminal)**\n```bash\nnpx @ipfs-shipyard/pinning-service-compliance -s http://localhost:6000 test-token-for-ipfs-pinning-compliance\n```\n\n**Test Mode Details:**\n- Creates a test user: `test@pinning.local`\n- Uses a fixed token: `test-token-for-ipfs-pinning-compliance`\n- Uses a separate test database: `data/pinning_test.db`\n- All operations are real (actual IPFS pinning, real database storage)\n\n## Upgrading\n\nThe installation script supports upgrades:\n\n1. Run `sudo ./install.sh`\n2. The script will detect the existing installation\n3. Creates a backup before upgrading\n4. Preserves your `.env` configuration\n5. Restarts the service with new binary\n\n## Legacy Firebase Backend\n\nThe original Firebase backend is still available in `main.go`. To use it:\n\n```bash\ngo build -o ./ipfs-pinning main.go\n```\n\nNote: Firebase backend requires `GOOGLE_APPLICATION_CREDENTIALS` environment variable.\n\n\n## UPDATE webui\n\n```\n# cd ~/pinning-service/pinning-webui/\n~/pinning-service/pinning-webui# git pull\n~/pinning-service/pinning-webui# VITE_GOOGLE_CLIENT_ID={YOUR GOGLE VITE} npm run build\n~/pinning-service/pinning-webui# cp -r dist/* /home/root/pinning-service/pinning-webui/dist/\n/pinning-service/pinning-webui# cp package.json package-lock.json /home/root/pinning-service/pinning-webui/\n~/pinning-service/pinning-webui# cd /home/root/pinning-service/pinning-webui\n/home/root/pinning-service/pinning-webui# npm install --production --ignore-scripts=false\n/home/root/pinning-service/pinning-webui# npm audit fix\n/home/root/pinning-service/pinning-webui# npm rebuild\n# systemctl restart fula-pinning-webui\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffunctionland%2Fpinning-service","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffunctionland%2Fpinning-service","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffunctionland%2Fpinning-service/lists"}