Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
af5b849
chore: bump required node version 20 -> 22
confleux Jun 9, 2025
d0406ce
chore: update dev deps
confleux Jun 10, 2025
fe91ae8
chore: update deps with minor changes
confleux Jun 10, 2025
3264837
chore: update gitignore
confleux Jun 10, 2025
2160c4b
chore: update eslint usage
confleux Jun 10, 2025
a5c2bb7
chore: update express
confleux Jun 10, 2025
f10d8c3
chore: update README, eslint config
confleux Jun 10, 2025
7b193b0
chore: update helia
confleux Jun 10, 2025
d046faa
chore: update unixfs
confleux Jun 10, 2025
4762439
chore: remove unused
confleux Jun 11, 2025
c343eac
chore: allow arbitrary storage dir
confleux Jun 11, 2025
cb3ef41
chore: update cron
confleux Jun 11, 2025
ab20a99
chore: separate default pino logger and pino-http logger
confleux Jun 15, 2025
cff7fb3
chore: add swagger
confleux Jun 15, 2025
b89688a
chore: update codebase
confleux Jun 17, 2025
786c79b
chore: update lint
confleux Jun 17, 2025
e2e2116
chore: update eslint to match prettier
confleux Jun 17, 2025
06fee9e
chore: update endpoints and swagger
confleux Jun 18, 2025
fe5694a
feat: add file unpin and gc
confleux Jun 18, 2025
0b5c4f3
chore: update enpoints, naming
confleux Jun 18, 2025
7be9ea5
chore: restructure project
confleux Jun 18, 2025
3b28daf
chore: rename err and e to error
confleux Jun 18, 2025
c43cd55
chore: rename err to error
confleux Jun 18, 2025
e4344c9
chore: update README
confleux Jun 18, 2025
62ebb24
chore: update swagger apis path
confleux Jun 18, 2025
186a561
chore: add test nodes to swagger
confleux Jun 18, 2025
098f1b5
chore: remove a todo
confleux Jun 18, 2025
9becdc8
chore: refactor filter logic
confleux Jun 22, 2025
c112a30
chore: mb as bytes
confleux Jun 22, 2025
dc814f6
chore: remove dublicate lines
confleux Jun 22, 2025
f1395da
chore: move var declaration and don't recreate array
confleux Jun 22, 2025
085756f
chore: change error messages
confleux Jun 22, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .eslintignore

This file was deleted.

3 changes: 0 additions & 3 deletions .eslintrc.json

This file was deleted.

8 changes: 6 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
node_modules
.idea
.DS_Store

node_modules/
.idea/
dist/
.adm-ipfs/

config.json5
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20.*
22.*
150 changes: 25 additions & 125 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,137 +1,37 @@
# ipfs-node
ADAMANT ipfs-node. Designed for downloading and exchanging files in the ADAMANT Messenger.
# ADAMANT IPFS node
A specialized IPFS node designed for the ADAMANT Messenger ecosystem, providing decentralized file storage and transfer capabilities with a REST API interface.

Unlike the standard libraries (helia or kubo), this ipfs-node is equipped with a web server for performing REST requests for downloading and receiving files.
## What It Is
This is a custom IPFS node built on top of Helia that serves as a private file storage and sharing system for the ADAMANT network.
Unlike standard IPFS implementations, it includes a built-in web server for HTTP-based file operations.

The plans also include the implementation of the Garbage Collector function, which will save disk space by removing unsent files.
Visit [Wiki: Todo](https://github.com/Adamant-im/ipfs-node/wiki/Todo) to see the future

## How to start
- You will need Node.js v20.11.1 (You can install via nvm: https://github.com/nvm-sh/nvm):
```bash
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
nvm install 20.11.1
```
- Cloning and building node:
```bash
git clone https://github.com/Adamant-im/ipfs-node.git
cd ipfs-node
npm i
npm run build
```
- Running node with [pm2](https://github.com/Unitech/pm2):
```bash
npm i -g pm2
pm2 start dist/index.js --name="IPFS node"
```


## How to configure
Using `config.default.json5` as a template, you can create various configuration files.
## Prerequisites
- Node.js v22.16.0 or higher
- npm package manager
- Sufficient disk space for file storage

For example:
`node dist/index.js test1` — this command will launch the server with the configuration from the file config.test1.json5

```jsonc
{
// List of IPFS ADAMANT nodes interacting between each other
nodes: [
{
name: "ipfs1",
multiAddr: "/ip4/194.163.154.252/tcp/4001/p2p/12D3KooWSUCe86zWfas1Lo1UQzXzquZgS81d1DpPPYAuTNjSyniq"
},
...
],
storeFolder: '.adm-ipfs', // File storage directory (the directory is set from the user’s home directory)
logLevel: 'debug', // Logging level: fatal, error, warn, info, debug, trace
peerDiscovery: {
// IPFS network nodes that will be used to search for new nodes
// Details: https://github.com/libp2p/js-libp2p/tree/main/packages/peer-discovery-bootstrap
bootstrap: [
'/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN',
...
],
// Addresses that helia will listen to
listen: [
'/ip4/0.0.0.0/tcp/4001',
]
},
serverPort: 4000, // API server deployment port
autoPeeringPeriod: '*/10 * * * * *',
diskUsageScanPeriod: '*/30 * * * * *', // Disk space scanning period. Set in cron format: '* * * * * *'
uploadLimitSizeBytes: 268435456, // Maximum upload file size (in bytes)
maxFileCount: 5, // Maximum upload count of files per request
findFileTimeout: 20000, // Time limit for searching for a file on the IPFS network
cors: {
// Allowed URLs to make request to node. Set using regular expressions
originRegexps: ['.*\.adamant\.im', 'adm.im', '.*\.vercel\.app', '.*\.surge\.sh', 'localhost:8080']
}
}
```
## How to start
For installation and configuration instructions, please refer to the following wiki pages:
- [Wiki: Installation](https://github.com/Adamant-im/ipfs-node/wiki/Installation)
- [Wiki: Configuration](https://github.com/Adamant-im/ipfs-node/wiki/Configuration)

These guides will help you to set up the node, configuring it, and preparing your environment for production use.

## How to use
To learn how to interact with the node, including available API endpoints and example requests, see:
- [Wiki: Usage examples](https://github.com/Adamant-im/ipfs-node/wiki/Usage-examples)
- [Wiki: API Specification](https://github.com/Adamant-im/ipfs-node/wiki/API-Specification)

### Upload file
Request body type: `form-data`

It should contain a "files" field, which can accept an array of files up to 5 pieces at a time.

#### Request
```POST /api/file/upload```
```bash
curl -i --location 'http://localhost:4000/api/file/upload' --form 'files=@"file.txt"'
```

#### Response
```
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
...

{"filesNames":["file.txt"],"cids":["bafkreif7v2d2wdyh6pz5y2pwmrpegfpdgh5u7n5vomxnbofraqhuk2wapm"]}
```

### Get file

#### Request
```GET /api/file/:cid```
```bash
curl -i --location 'http://localhost:4000/api/file/bafkreif7v2d2wdyh6pz5y2pwmrpegfpdgh5u7n5vomxnbofraqhuk2wapm'
```

#### Response
```
HTTP/1.1 200 OK
Content-Type: application/octet-stream
...
This documentation covers file upload/download, node status checks, and other REST API features.

Hello ipfs-node!
```
## License

### Get node info
Copyright © 2025 ADAMANT community developers

#### Request
```GET /api/node/info```
```bash
curl -i --location 'http://localhost:4000/api/node/info'
```
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

#### Response
```
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
...
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

{
"version": "0.0.1",
"timestamp": 1720614998797,
"heliaStatus": "started",
"peerId": "12D3KooWJSiMDfyDLK3EMe2567sSM1VKQVnUn2getimGqVTWqKX9",
"multiAddresses": [
"/ip4/127.0.0.1/tcp/4001/p2p/12D3KooWJSiMDfyDLK3EMe2567sSM1VKQVnUn2getimGqVTWqKX9",
"/ip4/62.72.43.99/tcp/4001/p2p/12D3KooWJSiMDfyDLK3EMe2567sSM1VKQVnUn2getimGqVTWqKX9"
],
"blockstoreSizeMb": 0.0009489059448242188,
"datastoreSizeMb": 0.006007194519042969,
"availableSizeInMb": 2257731
}
```
You should have received a copy of the [GNU General Public License](https://github.com/Adamant-im/ipfs-node/blob/master/LICENSE) along with this program. If not, see <http://www.gnu.org/licenses/>.
3 changes: 2 additions & 1 deletion config.default.json5
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
multiAddr: '/ip4/109.123.240.102/tcp/4001/p2p/12D3KooWHTvrWSTCXZFR2vS8Cbw17b5peK2aSBr8CmkyA96CDqiU'
}
],
storeFolder: '.adm-ipfs',
storeFolder: './.adm-ipfs',
logLevel: 'debug',
peerDiscovery: {
bootstrap: [
Expand All @@ -26,6 +26,7 @@
serverPort: 4000,
autoPeeringPeriod: '*/10 * * * * *',
diskUsageScanPeriod: '*/30 * * * * *',
garbageCollectorRunPeriod: '*/30 * * * * *',
uploadLimitSizeBytes: 268435456, // 256 Mb.
maxFileCount: 10,
findFileTimeout: 20000,
Expand Down
59 changes: 59 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import js from '@eslint/js'
import importPlugin from 'eslint-plugin-import'
import globals from 'globals'
import tseslint from 'typescript-eslint'
import json from '@eslint/json'
import markdown from '@eslint/markdown'
import prettier from 'eslint-config-prettier'
import { defineConfig, globalIgnores } from 'eslint/config'

export default defineConfig([
globalIgnores(['dist/', 'package-lock.json']),
{
files: ['**/*.{js,mjs,cjs,ts,mts,cts}'],
plugins: { js },
extends: ['js/recommended']
},
{
files: ['**/*.{js,mjs,cjs,ts,mts,cts}'],
languageOptions: { globals: globals.node }
},
tseslint.configs.recommended,
importPlugin.flatConfigs.typescript,
{
files: ['**/*.ts'],
plugins: { import: importPlugin },
rules: {
'import/order': [
'error',
{
groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'],
'newlines-between': 'always',
alphabetize: {
order: 'asc',
caseInsensitive: true
}
}
]
}
},
{
files: ['**/*.json'],
plugins: { json },
language: 'json/json',
extends: ['json/recommended']
},
{
files: ['**/*.json5'],
plugins: { json },
language: 'json/json5',
extends: ['json/recommended']
},
{
files: ['**/*.md'],
plugins: { markdown },
language: 'markdown/gfm',
extends: ['markdown/recommended']
},
prettier
])
Loading