Compare commits

..

No commits in common. "main" and "@collinjackson/zip-installer" have entirely different histories.

14 changed files with 339 additions and 736 deletions

View File

@ -1,64 +0,0 @@
name: ci
on:
push:
branches:
- main
pull_request:
branches:
- "**"
jobs:
build:
name: Lint CLI
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
sparse-checkout: |
clients/cli
proto
- name: Set up Rust
uses: dtolnay/rust-toolchain@stable
- name: Install protoc
uses: arduino/setup-protoc@v3
- name: Set up Rust cache
uses: Swatinem/rust-cache@v2
with:
workspaces: ./clients/cli
- name: Format
working-directory: clients/cli
run: |
rustfmt src/**/*.rs --check --edition 2021
- name: Build
working-directory: clients/cli
run: |
cargo build --profile=ci-build
- name: Run cargo clippy
working-directory: clients/cli
run: |
cargo clippy --profile=ci-build --no-deps --all-targets --workspace -- -D warnings
- name: Test
working-directory: clients/cli
run: |
cargo test --profile=ci-build --tests
- name: Ensure checked in generated files are up to date
run: |
if [ -n "$(git status --porcelain)" ]; then \
echo "There are uncommitted changes in working tree after building."; \
git status; \
git --no-pager diff; \
exit 1; \
else \
echo "Git working tree is clean"; \
fi;

View File

@ -1,96 +0,0 @@
# Contributing to the Nexus network
The Nexus network is contributor-friendly.
We welcome all contributions, no matter your experience with Rust or cryptography.
This document will help you get started. But first, **thank you for your interest in contributing!** We immensely appreciate quality contributions. This guide is intended to help you navigate the process.
The [Discord][discord] is always available for any concerns you may have that are not covered in this guide, or for any other questions or discussions you want to raise with the Nexus team or broader Nexus community.
### Code of Conduct
The Nexus network project adheres to the [Rust Code of Conduct][rust-coc]. This code of conduct describes the _minimum_ behavior
expected from all contributors.
Instances of violations of the Code of Conduct can be reported by contacting the Nexus team.
### Ways to contribute
There are three main ways to contribute:
1. **By reporting an issue:** If you believe that you have uncovered a bug in the Nexus zkVM, report it by creating a new issue in the [Github][gh] issue tracker. See below for an extended discussion on how to make a bug report most helpful.
2. **By adding information:** Even if collaborators are already aware of your issue, you can always provide additional context, such as further evidence in the form of reproduction steps, screenshots, code snippets, or logging outputs.
3. **By resolving an issue:** Typically this is done in the form of either demonstrating that the issue reported is not a problem after all in a polite, thoughtfully explained, and evidence supported manner, or by opening a pull request that fixes the underlying problem and participating in its review and refinement.
**Anybody can participate in any stage of contribution**. We urge you to participate in all discussions around bugs, feature requests, existing code, and PRs.
## Reporting Issues
#### Asking for help
If you have reviewed this document and existing documentation and still have questions or are still having problems, but don't quite know enough to create a bug report, then
you can get help by **starting a discussion**.
You can do so on the [Discord][discord].
#### Submitting a bug report
If you believe that you have uncovered a bug, please describe it to the best of your ability, and provide whatever context and evidence you have. Don't worry if you cannot provide every detail, just give us what you can. Contributors will ask follow-up questions if something is unclear.
As a starting point, in a bug report we will pretty much always want:
- the platform you are on, ideally both the operating system (Windows, macOS, or Linux) and the machine architecture (_e.g.,_ if you're using an M-series Mac) if you know them;
- console logs from the CLI or web application showing errors and status messages;
- concrete and comprehensive steps to reproduce the bug.
Code snippets should be as minimal as possible. It is always better if you can reproduce the bug with a small snippet that focuses on your Nexus zkVM usage rather than on the surrounding code in your project. This will help collaborators verify, reproduce, and zero in on a fix.
See [this guide][mcve] on how to create a minimal, complete, and verifiable example.
#### Submitting a feature request
Please include as detailed of an explanation as possible of the feature you would like, and add any additional context you think may be necessary or just helpful.
If you have examples of other tools that have the feature you are requesting, please include references/links to them as well.
## Resolving Issues
Pull requests are the way concrete changes are made to the code, documentation, and dependencies of the Nexus network.
Before making a large change, it is usually a good idea to first open an issue describing the change to solicit feedback and guidance.
This will increase the likelihood of the PR getting merged. Striking up a discussion the [Discord][discord] to let the community know
what you'll be working on can also be helpful for getting early feedback before diving in.
If you are working on a larger feature, we encourage you to open up a draft pull request and also check in with the [Discord][discord], to make sure that other
contributors are not duplicating work.
#### Discussion
You will probably get feedback or requests for changes to your pull request.
This is a regular and important part of the submission process, so don't be discouraged! Some reviewers may sign off on the pull
request right away, others may have more detailed comments or feedback. This is a necessary part of the process in order
to evaluate whether the changes are correct and necessary.
Remember to **always be aware of the person behind the code**. _How_ you communicate during reviews (of your code or others!) can have a significant impact on the success
of the pull request. We never want the cost of a change that makes the Nexus network better to be a valued contributor not
wanting to have anything to do with the project ever again. The goal is not just having good code. It's having a positive community that continues to turn good code into better code.
#### Abandoned or stale pull requests
If a pull request appears to be abandoned or stalled, it is polite to first check with the contributor to see if they
intend to continue the work before checking if they would mind if you took it over (especially if it just has minor revisions
remaining). When doing so, it is courteous to give the original contributor credit for the work they started, either by
preserving their name and e-mail address in the commit log, or by using the `Author: ` or `Co-authored-by: ` metadata
tag in the commits.
<sub><sup>_Adapted from the [Reth contributing guide][reth-contributing]_.</sub></sup>
[rust-coc]: https://github.com/rust-lang/rust/blob/master/CODE_OF_CONDUCT.md
[gh]: https://github.com/nexus-xyz/network-api
[discord]: https://discord.com/invite/nexus-xyz
[mcve]: https://stackoverflow.com/help/mcve
[reth-contributing]: https://github.com/paradigmxyz/reth/blob/main/CONTRIBUTING.md

View File

@ -1,6 +1,5 @@
# network-api # network-cli
This repository contains the Nexus network command-line interface and This repository contains the Nexus Network CLI and the interface definition for the Orchestrator server API.
the interface it uses to communicate with Nexus servers.
See the [CLI readme](./clients/cli/README.md) to get started. See the [CLI readme](./clients/cli/README.md) to get started.

274
clients/cli/Cargo.lock generated
View File

@ -24,7 +24,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"getrandom 0.2.15",
"once_cell", "once_cell",
"version_check", "version_check",
"zerocopy", "zerocopy",
@ -40,18 +39,14 @@ dependencies = [
] ]
[[package]] [[package]]
name = "alloc-no-stdlib" name = "allo-isolate"
version = "2.0.4" version = "0.1.25"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" checksum = "97b6d794345b06592d0ebeed8e477e41b71e5a0a49df4fc0e4184d5938b99509"
[[package]]
name = "alloc-stdlib"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece"
dependencies = [ dependencies = [
"alloc-no-stdlib", "anyhow",
"atomic",
"backtrace",
] ]
[[package]] [[package]]
@ -61,18 +56,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
[[package]] [[package]]
name = "android-tzdata" name = "android_log-sys"
version = "0.1.1" version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" checksum = "5ecc8056bf6ab9892dcd53216c83d1597487d7dacac16c8df6b877d127df9937"
[[package]] [[package]]
name = "android_system_properties" name = "android_logger"
version = "0.1.5" version = "0.13.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" checksum = "c494134f746c14dc653a35a4ea5aca24ac368529da5370ecf41fe0341c35772f"
dependencies = [ dependencies = [
"libc", "android_log-sys",
"env_logger",
"log",
"once_cell",
] ]
[[package]] [[package]]
@ -443,6 +441,12 @@ dependencies = [
"syn 2.0.71", "syn 2.0.71",
] ]
[[package]]
name = "atomic"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba"
[[package]] [[package]]
name = "atomic-waker" name = "atomic-waker"
version = "1.1.2" version = "1.1.2"
@ -567,25 +571,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae"
[[package]] [[package]]
name = "brotli" name = "build-target"
version = "3.5.0" version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d640d25bc63c50fb1f0b545ffd80207d2e10a4c965530809b40ba3386825c391" checksum = "832133bbabbbaa9fbdba793456a2827627a7d2b8fb96032fa1e7666d7895832b"
dependencies = [
"alloc-no-stdlib",
"alloc-stdlib",
"brotli-decompressor",
]
[[package]]
name = "brotli-decompressor"
version = "2.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f"
dependencies = [
"alloc-no-stdlib",
"alloc-stdlib",
]
[[package]] [[package]]
name = "bumpalo" name = "bumpalo"
@ -599,6 +588,12 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
[[package]]
name = "bytemuck"
version = "1.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773d90827bc3feecfb67fab12e24de0749aad83c74b9504ecde46237b5cd24e2"
[[package]] [[package]]
name = "byteorder" name = "byteorder"
version = "1.5.0" version = "1.5.0"
@ -627,20 +622,6 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
dependencies = [
"android-tzdata",
"iana-time-zone",
"js-sys",
"num-traits",
"wasm-bindgen",
"windows-targets 0.52.6",
]
[[package]] [[package]]
name = "clap" name = "clap"
version = "4.5.9" version = "4.5.9"
@ -710,6 +691,16 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "console_error_panic_hook"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc"
dependencies = [
"cfg-if",
"wasm-bindgen",
]
[[package]] [[package]]
name = "constant_time_eq" name = "constant_time_eq"
version = "0.3.1" version = "0.3.1"
@ -776,12 +767,42 @@ dependencies = [
"typenum", "typenum",
] ]
[[package]]
name = "dart-sys-fork"
version = "4.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "933dafff26172b719bb9695dd3715a1e7792f62dcdc8a5d4c740db7e0fedee8b"
dependencies = [
"cc",
]
[[package]]
name = "dashmap"
version = "4.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e77a43b28d0668df09411cb0bc9a8c2adc40f9a048afe863e05fd43251e8e39c"
dependencies = [
"cfg-if",
"num_cpus",
]
[[package]] [[package]]
name = "data-encoding" name = "data-encoding"
version = "2.6.0" version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2"
[[package]]
name = "delegate-attr"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51aac4c99b2e6775164b412ea33ae8441b2fde2dbf05a20bc0052a63d08c475b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.71",
]
[[package]] [[package]]
name = "derivative" name = "derivative"
version = "2.2.0" version = "2.2.0"
@ -843,6 +864,16 @@ dependencies = [
"cfg-if", "cfg-if",
] ]
[[package]]
name = "env_logger"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580"
dependencies = [
"log",
"regex",
]
[[package]] [[package]]
name = "equivalent" name = "equivalent"
version = "1.0.1" version = "1.0.1"
@ -892,6 +923,46 @@ version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
[[package]]
name = "flutter_rust_bridge"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aebee2d1d5b8b3cfbbb11919b44791b4e0f037328195efd3832c7f7e0c6c6c8b"
dependencies = [
"allo-isolate",
"android_logger",
"anyhow",
"build-target",
"bytemuck",
"byteorder",
"console_error_panic_hook",
"dart-sys-fork",
"delegate-attr",
"flutter_rust_bridge_macros",
"futures",
"js-sys",
"lazy_static",
"oslog",
"threadpool",
"tokio",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
]
[[package]]
name = "flutter_rust_bridge_macros"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c061770f5f09e99d6143612e95cfc1ba2ae773746fbe5826a9c914a533b0723"
dependencies = [
"hex",
"md-5",
"proc-macro2",
"quote",
"syn 2.0.71",
]
[[package]] [[package]]
name = "fnv" name = "fnv"
version = "1.0.7" version = "1.0.7"
@ -1176,15 +1247,6 @@ version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "home"
version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
dependencies = [
"windows-sys 0.52.0",
]
[[package]] [[package]]
name = "http" name = "http"
version = "1.1.0" version = "1.1.0"
@ -1298,29 +1360,6 @@ dependencies = [
"tracing", "tracing",
] ]
[[package]]
name = "iana-time-zone"
version = "0.1.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"wasm-bindgen",
"windows-core",
]
[[package]]
name = "iana-time-zone-haiku"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
dependencies = [
"cc",
]
[[package]] [[package]]
name = "idna" name = "idna"
version = "0.5.0" version = "0.5.0"
@ -1456,6 +1495,16 @@ dependencies = [
"regex-automata 0.1.10", "regex-automata 0.1.10",
] ]
[[package]]
name = "md-5"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf"
dependencies = [
"cfg-if",
"digest 0.10.7",
]
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.7.4" version = "2.7.4"
@ -1567,7 +1616,7 @@ dependencies = [
[[package]] [[package]]
name = "nexus-network" name = "nexus-network"
version = "0.3.4" version = "0.1.0"
dependencies = [ dependencies = [
"ark-bn254", "ark-bn254",
"ark-crypto-primitives", "ark-crypto-primitives",
@ -1584,20 +1633,18 @@ dependencies = [
"ark-test-curves", "ark-test-curves",
"ark-vesta", "ark-vesta",
"async-stream", "async-stream",
"chrono", "base64",
"clap", "clap",
"elf", "elf",
"flutter_rust_bridge",
"futures", "futures",
"getrandom 0.2.15", "getrandom 0.2.15",
"hex", "hex",
"home",
"iana-time-zone",
"jsonrpsee", "jsonrpsee",
"nexus-core", "nexus-core",
"prost", "prost",
"prost-build", "prost-build",
"rand 0.8.5", "rand 0.8.5",
"random_word",
"reqwest", "reqwest",
"serde", "serde",
"serde_json", "serde_json",
@ -1783,6 +1830,17 @@ dependencies = [
"vcpkg", "vcpkg",
] ]
[[package]]
name = "oslog"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8343ce955f18e7e68c0207dd0ea776ec453035685395ababd2ea651c569728b3"
dependencies = [
"cc",
"dashmap",
"log",
]
[[package]] [[package]]
name = "overload" name = "overload"
version = "0.1.1" version = "0.1.1"
@ -2057,20 +2115,6 @@ dependencies = [
"rand_core 0.5.1", "rand_core 0.5.1",
] ]
[[package]]
name = "random_word"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07eed67a16dde2cc3c7f65c072acd8d5b2e53d4aab95067c320db851c7651f29"
dependencies = [
"ahash",
"brotli",
"once_cell",
"paste",
"rand 0.8.5",
"unicase",
]
[[package]] [[package]]
name = "rayon" name = "rayon"
version = "1.10.0" version = "1.10.0"
@ -2153,6 +2197,7 @@ dependencies = [
"base64", "base64",
"bytes", "bytes",
"encoding_rs", "encoding_rs",
"futures-channel",
"futures-core", "futures-core",
"futures-util", "futures-util",
"h2", "h2",
@ -2590,6 +2635,15 @@ dependencies = [
"once_cell", "once_cell",
] ]
[[package]]
name = "threadpool"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa"
dependencies = [
"num_cpus",
]
[[package]] [[package]]
name = "tinyvec" name = "tinyvec"
version = "1.8.0" version = "1.8.0"
@ -2817,15 +2871,6 @@ version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
[[package]]
name = "unicase"
version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89"
dependencies = [
"version_check",
]
[[package]] [[package]]
name = "unicode-bidi" name = "unicode-bidi"
version = "0.3.15" version = "0.3.15"
@ -3025,15 +3070,6 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-core"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
dependencies = [
"windows-targets 0.52.6",
]
[[package]] [[package]]
name = "windows-sys" name = "windows-sys"
version = "0.48.0" version = "0.48.0"

View File

@ -1,6 +1,6 @@
[package] [package]
name = "nexus-network" name = "nexus-network"
version = "0.3.4" version = "0.1.0"
edition = "2021" edition = "2021"
[[bin]] [[bin]]
@ -10,37 +10,21 @@ path = "src/prover.rs"
[build-dependencies] [build-dependencies]
prost-build = "0.13" prost-build = "0.13"
[profile.dev]
opt-level = 1
[profile.release]
lto = "fat"
strip = true
codegen-units = 1
[profile.ci-build]
inherits = "dev"
opt-level = 0
debug = 0
strip = "none"
lto = false
codegen-units = 256
incremental = true
[dependencies] [dependencies]
async-stream = "0.3" async-stream = "0.3"
clap = { version = "4.5", features = ["derive"] } clap = { version = "4.5", features = ["derive"] }
futures = "0.3" futures = "0.3"
prost = "0.13" prost = "0.13"
rand = "0.8.5" rand = "0.8.5"
reqwest = { version = "0.12", features = ["json"] } reqwest = { version = "0.12", features = ["blocking"] }
tokio = { version = "1.38", features = ["full"] } tokio = { version = "1.38", features = ["full"] }
tokio-tungstenite = { version = "0.23", features = ["native-tls"] } tokio-tungstenite = { version = "0.23", features = ["native-tls"] }
tracing = "0.1" tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["std", "env-filter"] } tracing-subscriber = { version = "0.3", features = ["std", "env-filter"] }
uuid = { version = "1.9", features = ["v4", "fast-rng"] } uuid = { version = "1.9", features = ["v4", "fast-rng"] }
home = "0.5.9"
random_word = { version = "0.4.3", features = ["en"] } base64 = "0.22.1"
flutter_rust_bridge = "=2.1.0"
nexus-core = { git = "https://github.com/nexus-xyz/nexus-zkvm.git" } nexus-core = { git = "https://github.com/nexus-xyz/nexus-zkvm.git" }
getrandom = { version = "0.2", features = ["js"] } getrandom = { version = "0.2", features = ["js"] }
# Workaround for "failed to resolve patches for `https://github.com/rust-lang/crates.io-index`" # Workaround for "failed to resolve patches for `https://github.com/rust-lang/crates.io-index`"
@ -76,8 +60,6 @@ ark-grumpkin = "0.4.0"
ark-pallas = "0.4.0" ark-pallas = "0.4.0"
ark-vesta = "0.4.0" ark-vesta = "0.4.0"
ark-test-curves = { version = "0.4.2", features = ["bls12_381_curve"] } ark-test-curves = { version = "0.4.2", features = ["bls12_381_curve"] }
iana-time-zone = "0.1.60"
chrono = "0.4.38"
[patch.crates-io] [patch.crates-io]
ark-crypto-primitives = { git = "https://github.com/arkworks-rs/crypto-primitives", rev = "d27a5c8" } ark-crypto-primitives = { git = "https://github.com/arkworks-rs/crypto-primitives", rev = "d27a5c8" }
@ -100,3 +82,8 @@ ark-vesta = { git = "https://github.com/arkworks-rs/curves/", rev = "8c0256a" }
ark-bls12-381 = { git = "https://github.com/arkworks-rs/curves/", rev = "3fded1f" } ark-bls12-381 = { git = "https://github.com/arkworks-rs/curves/", rev = "3fded1f" }
zstd-sys = { git = "https://github.com/gyscos/zstd-rs" } zstd-sys = { git = "https://github.com/gyscos/zstd-rs" }
[profile.release]
strip = true
lto = true
codegen-units = 1

View File

@ -1,59 +1,16 @@
# Network CLI # network-cli
The command line interface (CLI) lets you run a prover node and contribute proofs to the Nexus network. Command line interface (CLI) for accessing the Nexus Network. Highest-performance option for proving.
It is the highest-performance option for proving.
## Prerequisites
If you don't have these dependencies already, install them first.
### Linux
```
sudo apt update
sudo apt upgrade
sudo apt install build-essential pkg-config libssl-dev git-all
```
### macOS
If you have [installed Homebrew](https://brew.sh/) to manage packages on OS X,
run this command to install Git.
```
brew install git
```
### Windows
[Install WSL](https://learn.microsoft.com/en-us/windows/wsl/install),
then see Linux instructions above.
## Quick start ## Quick start
``` ```
curl https://cli.nexus.xyz/ | sh curl https://network-cli.nexus.xyz/install.sh | sh
``` ```
If you do not already have Rust, you will be prompted to install it. If you do not already have Rust, you will be prompted to install it.
## Terms of Use
Use of the CLI is subject to the [Terms of Use](https://nexus.xyz/terms-of-use).
The first time you run it, it prompts you to accept the terms. To accept the terms
noninteractively (for example, in a continuous integration environment),
add `NONINTERACTIVE=1` before `sh`.
## Known issues ## Known issues
* Only the latest version of the CLI is currently supported. Currently only proving is supported. Submitting programs to the network is in private beta.
* Prebuilt binaries are not yet available. To request an API key, [contact us](https://forms.gle/183D9bcDHUdbxCV5A).
* Linking email to prover id is currently available on the web version only.
* Counting cycles proved is not yet available in the CLI.
* Only proving is supported. Submitting programs to the network is in private beta.
To request an API key, contact us at growth@nexus.xyz.
## Resources
* [Network FAQ](https://nexus.xyz/network#network-faqs)
* [Discord server](https://discord.gg/nexus-xyz)

View File

@ -1,19 +1,14 @@
use std::{error::Error, path::PathBuf, process::Command}; use std::{error::Error, path::PathBuf};
fn main() -> Result<(), Box<dyn Error>> { fn main() -> Result<(), Box<dyn Error>> {
let out_dir: PathBuf = "./src/generated/".into(); let out_dir: PathBuf = "./src/generated/".into();
let proto_file: PathBuf = "../../proto/orchestrator.proto".into(); let proto_file: PathBuf = "../../proto/orchestrator.proto".into();
let proto_dir = proto_file.parent().unwrap(); let proto_dir = proto_file.parent().unwrap();
match Command::new("protoc --version").spawn() { prost_build::Config::new()
Ok(_) => prost_build::Config::new() .out_dir(out_dir)
.out_dir(out_dir) .protoc_arg("--experimental_allow_proto3_optional")
.protoc_arg("--experimental_allow_proto3_optional") .compile_protos(&[&proto_file], &[proto_dir])?;
.compile_protos(&[&proto_file], &[proto_dir])?,
Err(_) => {
// Skipping protobuf compilation.
}
}
Ok(()) Ok(())
} }

View File

@ -1,82 +0,0 @@
use crate::config::{analytics_id, analytics_api_key};
use chrono::Datelike;
use chrono::Timelike;
use reqwest::header::{ACCEPT, CONTENT_TYPE};
use serde_json::{json, Value};
use std::{
env,
time::{SystemTime, UNIX_EPOCH},
};
pub fn track(
event_name: String,
description: String,
ws_addr_string: &str,
event_properties: Value,
) {
println!("{}", description);
let firebase_app_id = analytics_id(ws_addr_string);
let firebase_api_key = analytics_api_key(ws_addr_string);
if firebase_app_id.is_empty() {
return;
}
let local_now = chrono::offset::Local::now();
// For tracking events, we use the Firebase Measurement Protocol
// Firebase is mostly designed for mobile and web apps, but for our use case of a CLI,
// we can use the Measurement Protocol to track events by POST to a URL.
// The only thing that may be unexpected is that the URL we use includes a firebase key
// Firebase format for properties for Measurement protocol:
// https://developers.google.com/analytics/devguides/collection/protocol/ga4/reference?client_type=firebase#payload
// https://developers.google.com/analytics/devguides/collection/protocol/ga4/reference?client_type=firebase#payload_query_parameters
let mut properties = json!({
"time": SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis(),
// app_instance_id is the standard key Firebase uses this key to track the same user across sessions
// It is a bit redundant, but I wanted to keep the recommended format Firebase uses to minimize surprises
// I still left the distinct_id key as well for backwards compatibility
"app_instance_id": event_properties["prover_id"],
"distinct_id": event_properties["prover_id"],
"prover_type": "volunteer",
"client_type": "cli",
"operating_system": env::consts::OS,
"time_zone": iana_time_zone::get_timezone().unwrap(),
"local_hour": local_now.hour(),
"local_weekday_number_from_monday": local_now.weekday().number_from_monday(),
"ws_addr_string": ws_addr_string,
});
for (k, v) in event_properties.as_object().unwrap() {
properties[k] = v.clone();
}
// Firebase format for events
let body = json!({
"app_instance_id": event_properties["prover_id"],
"events": [{
"name": event_name,
"params": properties
}],
});
tokio::spawn(async move {
let client = reqwest::Client::new();
let _ = client
// URL is the Google Analytics endpoint for Firebase: https://stackoverflow.com/questions/50355752/firebase-analytics-from-remote-rest-api
.post(format!(
"https://www.google-analytics.com/mp/collect?firebase_app_id={}&api_secret={}",
firebase_app_id,
firebase_api_key
))
.body(format!("[{}]", body))
.header(ACCEPT, "text/plain")
.header(CONTENT_TYPE, "application/json")
.send()
.await
.unwrap()
.text()
.await
.unwrap();
});
}

View File

@ -1,78 +0,0 @@
// Debug version of analytics_id
#[cfg(debug_assertions)]
pub fn analytics_id(_ws_addr_string: &str) -> String {
// Use one of the tokens in the release version if debugging analytics
"".into()
}
// Debug version of analytics_api_key
#[cfg(debug_assertions)]
pub fn analytics_api_key(_ws_addr_string: &str) -> String {
// Use one of the tokens in the release version if debugging analytics
"".into()
}
// The following enum is used to determine the environment from the web socket string
#[derive(Debug)]
#[cfg(not(debug_assertions))]
enum Environment {
Dev,
Staging,
Beta,
Unknown,
}
// The web socket addresses for the different environments
#[cfg(not(debug_assertions))]
mod web_socket_urls {
pub const DEV: &str = "wss://dev.orchestrator.nexus.xyz:443/";
pub const STAGING: &str = "wss://staging.orchestrator.nexus.xyz:443/";
pub const BETA: &str = "wss://beta.orchestrator.nexus.xyz:443/";
}
// the firebase APP IDS by environment
#[cfg(not(debug_assertions))]
mod firebase {
pub const DEV_APP_ID: &str = "1:954530464230:web:f0a14de14ef7bcdaa99627";
pub const STAGING_APP_ID: &str = "1:222794630996:web:1758d64a85eba687eaaac1";
pub const BETA_APP_ID: &str = "1:279395003658:web:04ee2c524474d683d75ef3";
// Analytics keys for the different environments
// These are keys that allow the measurement protocol to write to the analytics database
// They are not sensitive. Worst case, if a malicious actor obtains the secret, they could potentially send false or misleading data to your GA4 property
pub const DEV_API_SECRET: &str = "8ySxiKrtT8a76zClqqO8IQ";
pub const STAGING_API_SECRET: &str = "OI7H53soRMSDWfJf1ittHQ";
pub const BETA_API_SECRET: &str = "gxxzKAQLSl-uYI0eKbIi_Q";
}
// Release versions (existing code)
#[cfg(not(debug_assertions))]
pub fn analytics_id(ws_addr_string: &str) -> String {
// Determine the environment from the web socket string (ws_addr_string)
let env = match ws_addr_string {
web_socket_urls::DEV => Environment::Dev,
web_socket_urls::STAGING => Environment::Staging,
web_socket_urls::BETA => Environment::Beta,
_ => Environment::Unknown,
};
// Return the appropriate Firebase App ID based on the environment
match env {
Environment::Dev => firebase::DEV_APP_ID.to_string(),
Environment::Staging => firebase::STAGING_APP_ID.to_string(),
Environment::Beta => firebase::BETA_APP_ID.to_string(),
Environment::Unknown => String::new(),
}
}
#[cfg(not(debug_assertions))]
pub fn analytics_api_key(ws_addr_string: &str) -> String {
match ws_addr_string {
web_socket_urls::DEV => firebase::DEV_API_SECRET.to_string(),
web_socket_urls::STAGING => firebase::STAGING_API_SECRET.to_string(),
web_socket_urls::BETA => firebase::BETA_API_SECRET.to_string(),
_ => String::new(),
}
}

View File

@ -1,11 +1,7 @@
// Copyright (c) 2024 Nexus. All rights reserved. // Copyright (c) 2024 Nexus. All rights reserved.
mod analytics;
mod config;
mod generated; mod generated;
use crate::analytics::track;
use std::borrow::Cow; use std::borrow::Cow;
use clap::Parser; use clap::Parser;
@ -15,9 +11,6 @@ use generated::pb::{
ProverRequest, ProverRequestRegistration, ProverResponse, ProverType, ProverRequest, ProverRequestRegistration, ProverResponse, ProverType,
}; };
use prost::Message as _; use prost::Message as _;
use random_word::Lang;
use serde_json::json;
use std::{fs, path::Path, time::SystemTime};
use tokio_tungstenite::tungstenite::protocol::{frame::coding::CloseCode, CloseFrame, Message}; use tokio_tungstenite::tungstenite::protocol::{frame::coding::CloseCode, CloseFrame, Message};
use tracing_subscriber::fmt::format::FmtSpan; use tracing_subscriber::fmt::format::FmtSpan;
use tracing_subscriber::EnvFilter; use tracing_subscriber::EnvFilter;
@ -29,10 +22,13 @@ use nexus_core::{
NexusVM, NexusVM,
}, },
prover::nova::{ prover::nova::{
init_circuit_trace, key::CanonicalSerialize, pp::gen_vm_pp, prove_seq_step, types::*, init_circuit_trace,
key::{CanonicalSerialize},
prove_seq_step,
types::*,
pp::gen_vm_pp,
}, },
}; };
use rand::RngCore;
use zstd::stream::Encoder; use zstd::stream::Encoder;
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
@ -44,9 +40,13 @@ struct Args {
#[arg(short, long, default_value_t = 443u16)] #[arg(short, long, default_value_t = 443u16)]
port: u16, port: u16,
/// Whether to hang up after the first proof /// Whether to connect using secure web sockets
#[arg(short, long, default_value_t = false)] #[arg(short, long, default_value_t = true)]
just_once: bool, use_https: bool,
/// Whether to loop and keep the connection open
#[arg(short, long, default_value_t = true)]
keep_listening: bool,
} }
#[tokio::main] #[tokio::main]
@ -61,104 +61,50 @@ async fn main() {
let ws_addr_string = format!( let ws_addr_string = format!(
"{}://{}:{}/prove", "{}://{}:{}/prove",
if args.port == 443 { "wss" } else { "ws" }, if args.use_https { "wss" } else { "ws" },
args.hostname, args.hostname,
args.port args.port
); );
let prover_id = format!("prover_{}", rand::random::<u32>());
let k = 4; let k = 4;
// TODO(collinjackson): Get parameters from a file or URL. // TODO(collinjackson): Get parameters from a file or URL.
let pp = gen_vm_pp::<C1, seq::SetupParams<(G1, G2, C1, C2, RO, SC)>>(k as usize, &()) let pp = gen_vm_pp::<C1, seq::SetupParams<(G1, G2, C1, C2, RO, SC)>>(k as usize, &())
.expect("error generating public parameters"); .expect("error generating public parameters");
// If the prover_id file is found, use the contents, otherwise generate a new random id println!(
// and store it. "{} supplying proofs to Orchestrator at {}",
let mut prover_id = format!( prover_id, &ws_addr_string
"{}-{}-{}",
random_word::gen(Lang::En),
random_word::gen(Lang::En),
rand::thread_rng().next_u32() % 100,
);
match home::home_dir() {
Some(path) if !path.as_os_str().is_empty() => {
let nexus_dir = Path::new(&path).join(".nexus");
prover_id = match fs::read(nexus_dir.join("prover-id")) {
Ok(buf) => String::from_utf8(buf).unwrap(),
Err(_) => {
let _ = fs::create_dir(nexus_dir.clone());
fs::write(nexus_dir.join("prover-id"), prover_id.clone()).unwrap();
prover_id
}
}
}
_ => {
println!("Unable to get home dir.");
}
};
track(
"connect".into(),
format!("Connecting to {}...", &ws_addr_string),
&ws_addr_string,
json!({"prover_id": prover_id}),
);
let (mut client, _) = tokio_tungstenite::connect_async(&ws_addr_string)
.await
.unwrap();
track(
"connected".into(),
"Connected.".into(),
&ws_addr_string,
json!({"prover_id": prover_id}),
); );
let registration = ProverRequest { let registration = ProverRequest {
contents: Some(prover_request::Contents::Registration( contents: Some(prover_request::Contents::Registration(
ProverRequestRegistration { ProverRequestRegistration {
prover_type: ProverType::Volunteer.into(), prover_type: ProverType::Volunteer.into(),
prover_id: prover_id.clone(), prover_id: prover_id,
estimated_proof_cycles_hertz: None, estimated_proof_cycles_hertz: None,
}, },
)), )),
}; };
let mut retries = 0; let (mut client, _) = tokio_tungstenite::connect_async(ws_addr_string)
let max_retries = 5; .await
.unwrap();
while let Err(e) = client client
.send(Message::Binary(registration.encode_to_vec())) .send(Message::Binary(registration.encode_to_vec()))
.await .await
{ .unwrap();
eprintln!( println!("Sent registration message...");
"Failed to send message: {:?}, attempt {}/{}",
e,
retries + 1,
max_retries
);
retries += 1;
if retries >= max_retries {
eprintln!("Max retries reached, exiting...");
break;
}
// Add a delay before retrying
tokio::time::sleep(tokio::time::Duration::from_secs(u64::pow(2, retries))).await;
}
track(
"register".into(),
format!("Your assigned prover identifier is {}.", prover_id),
&ws_addr_string,
json!({"ws_addr_string": ws_addr_string, "prover_id": prover_id}),
);
loop { loop {
let program_message = match client.next().await.unwrap().unwrap() { let program_message = match client.next().await.unwrap().unwrap() {
Message::Binary(b) => b, Message::Binary(b) => b,
_ => panic!("Unexpected message type"), _ => panic!("Unexpected message type"),
}; };
println!("Received program message...");
let program = ProverResponse::decode(program_message.as_slice()).unwrap(); let program = ProverResponse::decode(program_message.as_slice()).unwrap();
let Program::Rv32iElfBytes(elf_bytes) = program let Program::Rv32iElfBytes(elf_bytes) = program
@ -172,35 +118,32 @@ async fn main() {
let to_prove = program.to_prove.unwrap(); let to_prove = program.to_prove.unwrap();
let Input::RawBytes(input) = to_prove.input.unwrap().input.unwrap(); let Input::RawBytes(input) = to_prove.input.unwrap().input.unwrap();
track( println!(
"program".into(), "Received a {} byte program to prove with {} bytes of input",
format!( elf_bytes.len(),
"Received a {} byte program to prove with {} bytes of input", input.len()
elf_bytes.len(),
input.len()
),
&ws_addr_string,
json!({"prover_id": prover_id}),
); );
let mut vm: NexusVM<MerkleTrie> = let mut vm: NexusVM<MerkleTrie> =
parse_elf(elf_bytes.as_ref()).expect("error loading and parsing RISC-V instruction"); parse_elf(&elf_bytes.as_ref()).expect("error loading and parsing RISC-V instruction");
vm.syscalls.set_input(&input); vm.syscalls.set_input(&input);
let k = 4;
// TODO(collinjackson): Get outputs // TODO(collinjackson): Get outputs
let completed_trace = trace(&mut vm, k as usize, false).expect("error generating trace"); let completed_trace = trace(&mut vm, k as usize, false).expect("error generating trace");
let tr = init_circuit_trace(completed_trace).expect("error initializing circuit trace"); let tr = init_circuit_trace(completed_trace).expect("error initializing circuit trace");
let total_steps = tr.steps(); let total_steps = tr.steps();
println!("Program trace {} steps", total_steps);
let start: usize = match to_prove.step_to_start { let start: usize = match to_prove.step_to_start {
Some(step) => step as usize, Some(step) => step as usize,
None => 0, None => 0,
}; };
let steps_to_prove = match to_prove.steps_to_prove { let steps_to_prove = to_prove.steps_to_prove;
Some(steps) => steps as usize, let mut end: usize = match steps_to_prove {
Some(steps) => start + steps as usize,
None => total_steps, None => total_steps,
}; };
let mut end: usize = start + steps_to_prove;
if end > total_steps { if end > total_steps {
end = total_steps end = total_steps
} }
@ -219,85 +162,26 @@ async fn main() {
.unwrap(); .unwrap();
let z_st = tr.input(start).expect("error starting circuit trace"); let z_st = tr.input(start).expect("error starting circuit trace");
println!("Proving...");
let mut proof = IVCProof::new(&z_st); let mut proof = IVCProof::new(&z_st);
let mut completed_fraction = 0.0; println!("Proving from {} to {}", start, end);
let mut steps_proven = 0;
track(
"progress".into(),
format!(
"Program trace is {} steps. Proving {} steps starting at {}...",
total_steps, steps_to_prove, start
),
&ws_addr_string,
json!({
"completed_fraction": completed_fraction,
"steps_in_trace": total_steps,
"steps_to_prove": steps_to_prove,
"steps_proven": steps_proven,
"cycles_proven": steps_proven * k,
"k": k,
"prover_id": prover_id,
}),
);
let start_time = SystemTime::now();
let mut progress_time = start_time;
for step in start..end { for step in start..end {
proof = prove_seq_step(Some(proof), &pp, &tr).expect("error proving step"); proof = prove_seq_step(Some(proof), &pp, &tr).expect("error proving step");
steps_proven += 1; println!("Proved step {}", step);
completed_fraction = steps_proven as f32 / steps_to_prove as f32; let steps_proven = step - start + 1;
let progress = ProverRequest { let progress = ProverRequest {
contents: Some(prover_request::Contents::Progress(Progress { contents: Some(prover_request::Contents::Progress(Progress {
completed_fraction, completed_fraction: steps_proven as f32 / steps_to_prove.unwrap() as f32,
steps_in_trace: total_steps as i32, steps_in_trace: total_steps as i32,
steps_to_prove: steps_to_prove as i32, steps_to_prove: (end - start) as i32,
steps_proven, steps_proven: steps_proven as i32,
})), })),
}; };
let progress_duration = SystemTime::now().duration_since(progress_time).unwrap(); client
let cycles_proven = steps_proven * 4; .send(Message::Binary(progress.encode_to_vec()))
let proof_cycles_hertz = k as f64 * 1000.0 / progress_duration.as_millis() as f64; .await
track( .unwrap();
"progress".into(),
format!(
"Proved step {} at {:.2} proof cycles/sec.",
step, proof_cycles_hertz
),
&ws_addr_string,
json!({
"completed_fraction": completed_fraction,
"steps_in_trace": total_steps,
"steps_to_prove": steps_to_prove,
"steps_proven": steps_proven,
"cycles_proven": steps_proven * 4,
"k": k,
"progress_duration_millis": progress_duration.as_millis(),
"proof_cycles_hertz": proof_cycles_hertz,
"prover_id": prover_id,
}),
);
progress_time = SystemTime::now();
let mut retries = 0;
let max_retries = 5;
while let Err(e) = client.send(Message::Binary(progress.encode_to_vec())).await {
eprintln!(
"Failed to send message: {:?}, attempt {}/{}",
e,
retries + 1,
max_retries
);
retries += 1;
if retries >= max_retries {
eprintln!("Max retries reached, exiting...");
break;
}
// Add a delay before retrying
tokio::time::sleep(tokio::time::Duration::from_secs(u64::pow(2, retries))).await;
}
if step == end - 1 { if step == end - 1 {
let mut buf = Vec::new(); let mut buf = Vec::new();
let mut writer = Box::new(&mut buf); let mut writer = Box::new(&mut buf);
@ -312,36 +196,21 @@ async fn main() {
proof: Some(proof::Proof::NovaBytes(buf)), proof: Some(proof::Proof::NovaBytes(buf)),
})), })),
}; };
let duration = SystemTime::now().duration_since(start_time).unwrap();
let proof_cycles_hertz =
cycles_proven as f64 * 1000.0 / duration.as_millis() as f64;
client client
.send(Message::Binary(response.encode_to_vec())) .send(Message::Binary(response.encode_to_vec()))
.await .await
.unwrap(); .unwrap();
track(
"proof".into(),
format!(
"Proof sent! Overall speed was {:.2} proof cycles/sec.",
proof_cycles_hertz
),
&ws_addr_string,
json!({
"proof_duration_sec": duration.as_secs(),
"proof_duration_millis": duration.as_millis(),
"proof_cycles_hertz": proof_cycles_hertz,
"prover_id": prover_id,
}),
);
} }
} }
// TODO(collinjackson): Consider verifying the proof before sending it // TODO(collinjackson): Consider verifying the proof before sending it
// proof.verify(&public_params, proof.step_num() as _).expect("error verifying execution") // proof.verify(&public_params, proof.step_num() as _).expect("error verifying execution")
if args.just_once { println!("Proof sent!");
break;
} else { if args.keep_listening {
println!("Waiting for another program to prove..."); println!("Waiting for another program to prove...");
} else {
break;
} }
} }
@ -352,10 +221,5 @@ async fn main() {
})) }))
.await .await
.unwrap(); .unwrap();
track( println!("Sent proof and closed connection...");
"disconnect".into(),
"Sent proof and closed connection...".into(),
&ws_addr_string,
json!({ "prover_id": prover_id }),
);
} }

8
proto/generate_protobufs.sh Executable file
View File

@ -0,0 +1,8 @@
#!/bin/sh
mkdir -p clients/flutter/lib/src/generated
protoc --experimental_allow_proto3_optional --dart_out=grpc:clients/flutter/lib/src/generated -Iproto proto/orchestrator.proto
dart format clients/flutter/lib/src/generated
(cd clients/dummy_client && cargo build || echo clients/dummy_client not found, possibly due to a sparse checkout.)
(cd clients/cli && cargo build || echo clients/cli not found, possibly due to a sparse checkout.)
(cd orchestrator && cargo build || echo orchestrator/ not found, possibly due a sparse checkout.)

View File

@ -1,7 +1,7 @@
// Copyright (c) 2024 Nexus. All rights reserved. // Copyright (c) 2024 Nexus. All rights reserved.
// //
// If you use this protocol to communicate with Nexus's servers, // If you use this protocol to communicate with Nexus's servers,
// you must agree to the Terms of Service: https://nexus.xyz/terms-of-use // you must agree to the Terms of Service: https://nexus.xyz/tos
syntax = "proto3"; syntax = "proto3";

89
public/index.html Normal file
View File

@ -0,0 +1,89 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Welcome to Firebase Hosting</title>
<!-- update the version number as needed -->
<script defer src="/__/firebase/10.12.5/firebase-app-compat.js"></script>
<!-- include only the Firebase features as you need -->
<script defer src="/__/firebase/10.12.5/firebase-auth-compat.js"></script>
<script defer src="/__/firebase/10.12.5/firebase-database-compat.js"></script>
<script defer src="/__/firebase/10.12.5/firebase-firestore-compat.js"></script>
<script defer src="/__/firebase/10.12.5/firebase-functions-compat.js"></script>
<script defer src="/__/firebase/10.12.5/firebase-messaging-compat.js"></script>
<script defer src="/__/firebase/10.12.5/firebase-storage-compat.js"></script>
<script defer src="/__/firebase/10.12.5/firebase-analytics-compat.js"></script>
<script defer src="/__/firebase/10.12.5/firebase-remote-config-compat.js"></script>
<script defer src="/__/firebase/10.12.5/firebase-performance-compat.js"></script>
<!--
initialize the SDK after all desired features are loaded, set useEmulator to false
to avoid connecting the SDK to running emulators.
-->
<script defer src="/__/firebase/init.js?useEmulator=true"></script>
<style media="screen">
body { background: #ECEFF1; color: rgba(0,0,0,0.87); font-family: Roboto, Helvetica, Arial, sans-serif; margin: 0; padding: 0; }
#message { background: white; max-width: 360px; margin: 100px auto 16px; padding: 32px 24px; border-radius: 3px; }
#message h2 { color: #ffa100; font-weight: bold; font-size: 16px; margin: 0 0 8px; }
#message h1 { font-size: 22px; font-weight: 300; color: rgba(0,0,0,0.6); margin: 0 0 16px;}
#message p { line-height: 140%; margin: 16px 0 24px; font-size: 14px; }
#message a { display: block; text-align: center; background: #039be5; text-transform: uppercase; text-decoration: none; color: white; padding: 16px; border-radius: 4px; }
#message, #message a { box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24); }
#load { color: rgba(0,0,0,0.4); text-align: center; font-size: 13px; }
@media (max-width: 600px) {
body, #message { margin-top: 0; background: white; box-shadow: none; }
body { border-top: 16px solid #ffa100; }
}
</style>
</head>
<body>
<div id="message">
<h2>Welcome</h2>
<h1>Firebase Hosting Setup Complete</h1>
<p>You're seeing this because you've successfully setup Firebase Hosting. Now it's time to go build something extraordinary!</p>
<a target="_blank" href="https://firebase.google.com/docs/hosting/">Open Hosting Documentation</a>
</div>
<p id="load">Firebase SDK Loading&hellip;</p>
<script>
document.addEventListener('DOMContentLoaded', function() {
const loadEl = document.querySelector('#load');
// // 🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥
// // The Firebase SDK is initialized and available here!
//
// firebase.auth().onAuthStateChanged(user => { });
// firebase.database().ref('/path/to/ref').on('value', snapshot => { });
// firebase.firestore().doc('/foo/bar').get().then(() => { });
// firebase.functions().httpsCallable('yourFunction')().then(() => { });
// firebase.messaging().requestPermission().then(() => { });
// firebase.storage().ref('/path/to/ref').getDownloadURL().then(() => { });
// firebase.analytics(); // call to activate
// firebase.analytics().logEvent('tutorial_completed');
// firebase.performance(); // call to activate
//
// // 🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥
try {
let app = firebase.app();
let features = [
'auth',
'database',
'firestore',
'functions',
'messaging',
'storage',
'analytics',
'remoteConfig',
'performance',
].filter(feature => typeof app[feature] === 'function');
loadEl.textContent = `Firebase SDK loaded with ${features.join(', ')}`;
} catch (e) {
console.error(e);
loadEl.textContent = 'Error loading the Firebase SDK, check the console.';
}
});
</script>
</body>
</html>

View File

@ -2,30 +2,18 @@
rustc --version || curl https://sh.rustup.rs -sSf | sh rustc --version || curl https://sh.rustup.rs -sSf | sh
NEXUS_HOME=$HOME/.nexus NEXUS_HOME=$HOME/.nexus
CLI_ZIP=/tmp/nexus-network-api.zip
while [ -z "$NONINTERACTIVE" ]; do curl -L --verbose "https://docs.google.com/uc?export=download&id=1kcbEeKpVEyvIqL-_cgR5sYdZe_fOEPs6" > $CLI_ZIP
read -p "Do you agree to the Nexus Beta Terms of Use (https://nexus.xyz/terms-of-use)? (Y/n) " yn </dev/tty if [ -d "$NEXUS_HOME" ]; then
case $yn in echo "$NEXUS_HOME exists. Updating.";
[Nn]* ) exit;; (cd $NEXUS_HOME && rm -rf network-api && unzip $CLI_ZIP)
[Yy]* ) break;; # TODO: Once GitHub repo is public, do this instead
"" ) break;; # (cd $NEXUS_HOME && git pull)
* ) echo "Please answer yes or no.";;
esac
done
git --version 2>&1 >/dev/null
GIT_IS_AVAILABLE=$?
if [ $GIT_IS_AVAILABLE != 0 ]; then
echo Unable to find git. Please install it and try again.
exit 1;
fi
if [ -d "$NEXUS_HOME/network-api" ]; then
echo "$NEXUS_HOME/network-api exists. Updating.";
(cd $NEXUS_HOME/network-api && git pull)
else else
# TODO: Once GitHub repo is public, do this instead
# git clone git@github.com:nexus-xyz/network-cli $NEXUS_HOME
mkdir -p $NEXUS_HOME mkdir -p $NEXUS_HOME
(cd $NEXUS_HOME && git clone https://github.com/nexus-xyz/network-api) (cd $NEXUS_HOME && unzip $CLI_ZIP)
fi fi
(cd $NEXUS_HOME/network-api/clients/cli && cargo run --release --bin prover -- beta.orchestrator.nexus.xyz) (cd $NEXUS_HOME/network-api/clients/cli && cargo run --release --bin prover -- beta.orchestrator.nexus.xyz)