diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..1ee0d4d --- /dev/null +++ b/.dockerignore @@ -0,0 +1,7 @@ +node_modules +npm-debug.log +build +.dockerignore +**/.git +**/.DS_Store +**/node_modules diff --git a/.github/logo.svg b/.github/logo.svg new file mode 100644 index 0000000..b4da076 --- /dev/null +++ b/.github/logo.svg @@ -0,0 +1,129 @@ + + diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..9dc1868 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,67 @@ +name: Build + +on: + pull_request: + branches: + - master + types: [opened, synchronize] + paths-ignore: + - '**/*.md' + push: + # Build for the master branch. + branches: + - master + release: + types: + - published + workflow_dispatch: + inputs: + ref: + description: 'Ref to build [default: latest master; examples: v0.4.0, 9595da7d83efc330ca0bc94bef482e4edfbcf8fd]' + required: false + default: '' + deploy: + description: 'Deploy to production [default: false; examples: true, false]' + required: false + default: 'false' + +jobs: + build_release: + name: Build and deploy + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.inputs.ref }} + # Allows to fetch all history for all branches and tags. Need this for proper versioning. + fetch-depth: 0 + + - name: Build + run: make release + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: release + path: ./archive.fs.neo.org-*.tar.gz + if-no-files-found: error + + - name: Attach binary to the release as an asset + if: ${{ github.event_name == 'release' }} + run: gh release upload ${{ github.event.release.tag_name }} ./archive.fs.neo.org-*.tar.gz + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Publish to NeoFS + if: ${{ github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && github.event.inputs.deploy == 'true') }} + uses: nspcc-dev/gh-push-to-neofs@master + with: + NEOFS_WALLET: ${{ secrets.NEOFS_WALLET }} + NEOFS_WALLET_PASSWORD: ${{ secrets.NEOFS_WALLET_PASSWORD }} + NEOFS_NETWORK_DOMAIN: ${{ vars.NEOFS_NETWORK_DOMAIN }} + NEOFS_HTTP_GATE: ${{ vars.NEOFS_HTTP_GATE }} + STORE_OBJECTS_CID: ${{ vars.STORE_OBJECTS_CID }} + PATH_TO_FILES_DIR: archive.fs.neo.org + STRIP_PREFIX: true + REPLACE_CONTAINER_CONTENTS: true diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..c31d95e --- /dev/null +++ b/Makefile @@ -0,0 +1,43 @@ +#!/usr/bin/make -f + +SHELL = bash + +VERSION ?= "$(shell git describe --tags --match "v*" --abbrev=8 2>/dev/null | sed -r 's,^v([0-9]+\.[0-9]+)\.([0-9]+)(-.*)?$$,\1 \2 \3,' | while read mm patch suffix; do if [ -z "$$suffix" ]; then echo $$mm.$$patch; else patch=`expr $$patch + 1`; echo $$mm.$${patch}-pre$$suffix; fi; done)" +SITE_DIR ?= archive.fs.neo.org +RELEASE_DIR ?= $(SITE_DIR)-$(VERSION) +RELEASE_PATH ?= $(SITE_DIR)-$(VERSION).tar.gz +CURRENT_UID ?= $(shell id -u $$USER) + +PORT = 3000 + +$(SITE_DIR): + docker run \ + -v $$(pwd)/src:/usr/src/app/src \ + -v $$(pwd)/public:/usr/src/app/public \ + -v $$(pwd)/package.json:/usr/src/app/package.json \ + -v $$(pwd)/$(SITE_DIR):/usr/src/app/$(SITE_DIR) \ + -e CURRENT_UID=$(CURRENT_UID) \ + -w /usr/src/app node:14-alpine \ + sh -c 'npm install && REACT_APP_VERSION=$(VERSION) npm run build && chown -R $$CURRENT_UID: $(SITE_DIR)' + +start: + docker run \ + -p $(PORT):3000 \ + -v `pwd`:/usr/src/app \ + -w /usr/src/app node:14-alpine \ + sh -c 'npm install --silent && npm run build && npm install -g serve && serve -s $(SITE_DIR) -p 3000' + +release: $(SITE_DIR) + cp $(SITE_DIR)/index.html $(SITE_DIR)/about + @ln -sf $(SITE_DIR) $(RELEASE_DIR) + @tar cfvhz $(RELEASE_PATH) $(RELEASE_DIR) + +clean: + @echo "Cleaning up ..." + @rm -rf $(SITE_DIR) $(RELEASE_DIR) $(RELEASE_PATH) + +release_name: + @echo $(RELEASE_PATH) + +version: + @echo $(VERSION) diff --git a/README.md b/README.md new file mode 100644 index 0000000..7ff664a --- /dev/null +++ b/README.md @@ -0,0 +1,31 @@ +
+ +
++ NeoFS is a decentralized distributed object storage integrated with the Neo Blockchain. +
+ +--- +![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/nspcc-dev/archive-fs-neo-org?sort=semver) +![License](https://img.shields.io/github/license/nspcc-dev/archive-fs-neo-org.svg?style=popout) + +# Overview + +Archive.NeoFS – Offline Synchronization Package. Download an offline block dump up to a certain block height. This web application is built on the React framework. + +# Requirements + +- docker +- make +- node (`14+`) + +# Make instructions + +* Compile the build using `make` (will be generated in `archive-fs-neo-org` dir) +* Start app using `make start PORT=3000` (PORT=3000 by default) +* Clean up cache directories using `make clean` +* Get release directory with tar.gz using `make release` + +# License + +- [GNU General Public License v3.0](LICENSE) diff --git a/package.json b/package.json new file mode 100644 index 0000000..f2ab157 --- /dev/null +++ b/package.json @@ -0,0 +1,42 @@ +{ + "name": "archive-fs-neo-org", + "version": "0.0.1", + "private": true, + "dependencies": { + "@fortawesome/fontawesome-svg-core": "^6.4.0", + "@fortawesome/free-brands-svg-icons": "^6.4.0", + "@fortawesome/free-regular-svg-icons": "^6.4.0", + "@fortawesome/free-solid-svg-icons": "^6.4.0", + "@fortawesome/react-fontawesome": "^0.2.0", + "@types/react": "^18.2.41", + "@types/react-dom": "^18.2.17", + "base-58": "^0.0.1", + "bulma": "^0.9.4", + "react": "^17.0.2", + "react-bulma-components": "^4.1.0", + "react-dom": "^17.0.2", + "react-router-dom": "^6.10.0" + }, + "scripts": { + "start": "REACT_APP_VERSION=$(make version) GENERATE_SOURCEMAP=false react-scripts start", + "build": "GENERATE_SOURCEMAP=false BUILD_PATH='./archive.fs.neo.org' react-scripts build", + "test": "react-scripts test", + "eject": "react-scripts eject" + }, + "eslintConfig": { + "extends": [ + "react-app", + "react-app/jest" + ] + }, + "browserslist": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "devDependencies": { + "dotenv": "^16.0.3", + "react-scripts": "^5.0.1", + "typescript": "^4.9.5" + } +} diff --git a/public/img/close.svg b/public/img/close.svg new file mode 100644 index 0000000..73396e3 --- /dev/null +++ b/public/img/close.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/cover.png b/public/img/cover.png new file mode 100644 index 0000000..2dc9624 Binary files /dev/null and b/public/img/cover.png differ diff --git a/public/img/favicon.ico b/public/img/favicon.ico new file mode 100644 index 0000000..5a1c553 Binary files /dev/null and b/public/img/favicon.ico differ diff --git a/public/img/logo.svg b/public/img/logo.svg new file mode 100644 index 0000000..2081f97 --- /dev/null +++ b/public/img/logo.svg @@ -0,0 +1,103 @@ + + diff --git a/public/img/socials/github.svg b/public/img/socials/github.svg new file mode 100644 index 0000000..aa05db9 --- /dev/null +++ b/public/img/socials/github.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/socials/medium.svg b/public/img/socials/medium.svg new file mode 100644 index 0000000..08a9433 --- /dev/null +++ b/public/img/socials/medium.svg @@ -0,0 +1,6 @@ + + \ No newline at end of file diff --git a/public/img/socials/neo.svg b/public/img/socials/neo.svg new file mode 100644 index 0000000..75e2d8b --- /dev/null +++ b/public/img/socials/neo.svg @@ -0,0 +1,64 @@ + + diff --git a/public/img/socials/neo_spcc.svg b/public/img/socials/neo_spcc.svg new file mode 100644 index 0000000..d0b04c6 --- /dev/null +++ b/public/img/socials/neo_spcc.svg @@ -0,0 +1,108 @@ + + diff --git a/public/img/socials/twitter.svg b/public/img/socials/twitter.svg new file mode 100644 index 0000000..1970575 --- /dev/null +++ b/public/img/socials/twitter.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/socials/youtube.svg b/public/img/socials/youtube.svg new file mode 100644 index 0000000..6c30aa1 --- /dev/null +++ b/public/img/socials/youtube.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/index.html b/public/index.html new file mode 100644 index 0000000..89f78c0 --- /dev/null +++ b/public/index.html @@ -0,0 +1,28 @@ + + + + +Archive.NeoFS is a web application that allows users to create blockchain archives of any span (from block 0 to the current block or a custom range) directly in the browser. It operates fully client-side, leveraging standard NeoFS REST gateway APIs and in-browser streaming techniques to efficiently fetch and store blocks without requiring additional backend processing.
+The service supports four networks: mainnet, testnet, NeoFS mainnet, and NeoFS testnet. It interacts with the NeoFS REST gateway to retrieve blockchain data stored in NeoFS objects and assembles them into a structured archive format (.acc), that is compatible with both C# Neo node and NeoGo.
+Frontend part first determines the latest available block in the selected network using the getblockcount
method in the RPC request. Each block is stored as a separate object with a unique Object ID (OID), while index files contain references to batches of 128,000 blocks, mapping block indices to their corresponding OIDs. It then, using NeoFS REST gateway, the program first retrieves index files using SEARCH, then extracts object IDs then fetches these objects (containing blocks) via GET NeoFS request.
The process runs entirely in the browser using the showSaveFilePicker
API for file handling and the WritableStream
API for efficient in-browser streaming. Downloaded blocks are written directly into an archive .acc
file, ensuring minimal memory overhead. However, due to API limitations, this feature is only supported in modern browsers: Chrome 86+ (recommended).
{modal.params}
+ {typeof modal.btn === 'function' && ( + + )} + {modal.btn === 'about' && ( + + )} +Easily download an offline package of blocks up to a specific block height.
+Manual steps:
+start
and end
snapshot option for the data range;network
;.acc
file to download to your device. 🚀For the best experience, please use Chrome 86+.
+