Compare commits

..

1 Commits

Author SHA1 Message Date
Simon Wicky 60731ad2d4 test 2026-01-08 10:07:22 +01:00
534 changed files with 5475 additions and 47328 deletions
-3
View File
@@ -1,5 +1,2 @@
nym-validator-rewarder/.sqlx/** diff=nodiff
nym-node-status-api/nym-node-status-api/.sqlx/** diff=nodiff
# Use bd merge for beads JSONL files
.beads/beads.jsonl merge=beads
+1 -1
View File
@@ -25,7 +25,7 @@ Steps to reproduce the behaviour, if you're familiar with BDD syntax, please wri
*An example:*
- Given I was setting up a mix-node following the instructions in the docs
- And I successfully bonded my node via the wallet
- And I successfully bonded my node via the the wallet
- When I went to start my mixnode
- Then I was presented with an error
@@ -1,43 +0,0 @@
name: Publish to crates.io (dry run)
on:
workflow_dispatch:
inputs:
version:
description: "Version to publish (e.g. 1.21.0)"
required: true
type: string
jobs:
publish-dry-run:
runs-on: arc-ubuntu-22.04-dind
steps:
- name: Checkout repo
uses: actions/checkout@v6
- name: Install rust toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- name: Install cargo-workspaces
run: cargo install cargo-workspaces
- name: Bump versions (local only)
run: |
cargo workspaces version ${{ inputs.version }} \
--no-git-commit \
--no-git-tag \
--no-git-push \
--yes
# Note: Dry run may show cascading dependency errors because packages
# aren't actually uploaded. Check if the missing dependency has an
# "aborting upload due to dry run" message earlier in the output - if so,
# it would succeed in a real publish since cargo-workspaces publishes in
# dependency order. cargo-workspaces doesn't fail on err, so there isn't
# a good way to check this at the moment.
- name: Publish (dry run)
run: cargo workspaces publish --from-git --dry-run --allow-dirty
-47
View File
@@ -1,47 +0,0 @@
name: Publish to crates.io
on:
workflow_dispatch:
inputs:
version:
description: "Version to publish (e.g. 1.21.0)"
required: true
type: string
jobs:
publish:
runs-on: arc-ubuntu-22.04-dind
steps:
- name: Checkout repo
uses: actions/checkout@v6
- name: Install rust toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- name: Install cargo-workspaces
run: cargo install cargo-workspaces
# - name: Configure git
# run: |
# git config user.name "github-actions[bot]"
# git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Bump versions
run: |
cargo workspaces version ${{ inputs.version }} \
--no-git-push \
--no-git-tag \
--yes
- name: Publish
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
run: cargo workspaces publish --from-git --no-git-commit
# - name: Push version commit
# run: |
# git push origin HEAD
+1 -13
View File
@@ -64,16 +64,4 @@ nym-api/redocly/formatted-openapi.json
**/settings.sql
**/enter_db.sh
*.profraw
.beads
CLAUDE.md
docs
.claude
.superego
# Superego (machine-specific paths)
.superego/
.claude/hooks/superego/
.claude/settings.json
/notes
*.profraw
-138
View File
@@ -4,144 +4,6 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
## [Unreleased]
## [2026.2-oscypek] (2026-01-27)
- bugfix: downgrade gateway protocol to clients proposed version ([#6377])
- bugfix: ack fix ([#6364])
- Cherry pick/api urls oscypek ([#6348])
- Update nix to v0.30.1 ([#6316])
- Deriving Serialize for GatewayData ([#6314])
- chore: remove repetitive words in comment ([#6313])
- [bugfix] Sqlite transaction escalation was causing errors ([#6299])
- DNS static table pre-resolve ([#6297])
- Add Copy+Clone to nym_api_provider::Config ([#6296])
- [chore] clippy fixes and use fixed rust version from REQUIRED_RUSTC_VERSION ([#6295])
- build(deps): bump SonarSource/sonarqube-scan-action from 6 to 7 ([#6294])
- build(deps): bump mikefarah/yq from 4.49.2 to 4.50.1 ([#6293])
- build(deps): bump actions/upload-artifact from 5 to 6 ([#6292])
- build(deps): bump actions/download-artifact from 6 to 7 ([#6291])
- build(deps): bump js-yaml from 3.14.1 to 3.14.2 in /documentation/docs ([#6290])
- build(deps): bump next from 15.4.9 to 15.4.10 in /nym-node-status-api/nym-node-status-ui ([#6289])
- build(deps): bump next from 14.2.33 to 14.2.35 ([#6288])
- LP Registration + Telescoping + Gateway Probe Localnet Mode ([#6286])
- build(deps): bump next from 15.5.7 to 15.5.9 in /documentation/docs ([#6285])
- build(deps): bump next from 15.4.7 to 15.4.9 in /nym-node-status-api/nym-node-status-ui ([#6284])
- Minor DNS improvements ([#6283])
- HTTP client without default features ([#6281])
- DNS: reduce number of attempts ([#6278])
- [bugfix] use proper mixing delay instead of poisson delay in cover traffic ([#6269])
- build(deps): bump node-forge from 1.3.1 to 1.3.3 in /wasm/zknym-lib/internal-dev ([#6261])
- build(deps-dev): bump node-forge from 1.3.1 to 1.3.3 in /wasm/mix-fetch/internal-dev ([#6260])
- build(deps-dev): bump node-forge from 1.3.1 to 1.3.2 in /wasm/client/internal-dev ([#6251])
- build(deps): bump node-forge from 1.3.1 to 1.3.2 in /nym-credential-proxy/vpn-api-lib-wasm/internal-dev ([#6250])
- [Feature] Fallback gateway listener and remove legacy key support ([#6249])
- build(deps-dev): bump node-forge from 1.3.0 to 1.3.2 in /clients/native/examples/js-examples/websocket ([#6248])
- build(deps): bump node-forge from 1.3.1 to 1.3.2 ([#6246])
- build(deps): bump pnpm/action-setup from 4.1.0 to 4.2.0 ([#6245])
- build(deps): bump actions/download-artifact from 5 to 6 ([#6244])
- build(deps): bump actions/checkout from 4 to 6 ([#6243])
- build(deps): bump mikefarah/yq from 4.48.1 to 4.49.2 ([#6242])
- build(deps): bump actions/upload-artifact from 4 to 5 ([#6241])
- fix: fix assertion ([#6238])
- Initial changes to support extra configurable parameters and to print… ([#6237])
- Data Observatory ([#6172])
[#6377]: https://github.com/nymtech/nym/pull/6377
[#6364]: https://github.com/nymtech/nym/pull/6364
[#6348]: https://github.com/nymtech/nym/pull/6348
[#6316]: https://github.com/nymtech/nym/pull/6316
[#6314]: https://github.com/nymtech/nym/pull/6314
[#6313]: https://github.com/nymtech/nym/pull/6313
[#6299]: https://github.com/nymtech/nym/pull/6299
[#6297]: https://github.com/nymtech/nym/pull/6297
[#6296]: https://github.com/nymtech/nym/pull/6296
[#6295]: https://github.com/nymtech/nym/pull/6295
[#6294]: https://github.com/nymtech/nym/pull/6294
[#6293]: https://github.com/nymtech/nym/pull/6293
[#6292]: https://github.com/nymtech/nym/pull/6292
[#6291]: https://github.com/nymtech/nym/pull/6291
[#6290]: https://github.com/nymtech/nym/pull/6290
[#6289]: https://github.com/nymtech/nym/pull/6289
[#6288]: https://github.com/nymtech/nym/pull/6288
[#6286]: https://github.com/nymtech/nym/pull/6286
[#6285]: https://github.com/nymtech/nym/pull/6285
[#6284]: https://github.com/nymtech/nym/pull/6284
[#6283]: https://github.com/nymtech/nym/pull/6283
[#6281]: https://github.com/nymtech/nym/pull/6281
[#6278]: https://github.com/nymtech/nym/pull/6278
[#6269]: https://github.com/nymtech/nym/pull/6269
[#6261]: https://github.com/nymtech/nym/pull/6261
[#6260]: https://github.com/nymtech/nym/pull/6260
[#6251]: https://github.com/nymtech/nym/pull/6251
[#6250]: https://github.com/nymtech/nym/pull/6250
[#6249]: https://github.com/nymtech/nym/pull/6249
[#6248]: https://github.com/nymtech/nym/pull/6248
[#6246]: https://github.com/nymtech/nym/pull/6246
[#6245]: https://github.com/nymtech/nym/pull/6245
[#6244]: https://github.com/nymtech/nym/pull/6244
[#6243]: https://github.com/nymtech/nym/pull/6243
[#6242]: https://github.com/nymtech/nym/pull/6242
[#6241]: https://github.com/nymtech/nym/pull/6241
[#6238]: https://github.com/nymtech/nym/pull/6238
[#6237]: https://github.com/nymtech/nym/pull/6237
[#6172]: https://github.com/nymtech/nym/pull/6172
## [2026.1-niolo] (2026-01-13)
- bugfix: mozzarella -> niolo config migration ([#6259])
- chore: remove run DKG migration ([#6253])
- bugfix: reexposed 'derive_extended_private_key' ([#6247])
- Bump js-yaml from 3.14.1 to 3.14.2 in /sdk/typescript/codegen/contract-clients ([#6231])
- Statistics API v2 ([#6227])
- Bump golang.org/x/crypto from 0.39.0 to 0.45.0 in /nym-gateway-probe/netstack_ping ([#6220])
- Update chain registry link ([#6219])
- Bump glob from 10.3.4 to 10.5.0 in /documentation/scripts/post-process ([#6216])
- Bump js-yaml from 4.1.0 to 4.1.1 in /sdk/typescript/tests/integration-tests/mix-fetch ([#6215])
- gateway-probe fixes for run-local ([#6212])
- chore: updated default endpoint for retrieving attestation.json ([#6207])
- chore: remove support for legacy mixnode within the performance contract ([#6205])
- feat: upgrade mode: VPN adjustments ([#6189])
- Bump min-document from 2.19.0 to 2.19.1 ([#6181])
- Bump next from 15.4.1 to 15.4.7 in /nym-node-status-api/nym-node-status-ui ([#6180])
- feat: merge intermediate upgrade mode changes ([#6174])
- Add weighted scoring to NS API ([#6144])
- build(deps): bump mikefarah/yq from 4.47.1 to 4.48.1 ([#6107])
- build(deps): bump SonarSource/sonarqube-scan-action from 5 to 6 in /.github/workflows ([#6068])
- build(deps): bump tar-fs from 3.0.9 to 3.1.1 in /sdk/typescript/tests/integration-tests/mix-fetch ([#6063])
- build(deps): bump ammonia from 4.1.1 to 4.1.2 ([#6057])
- build(deps): bump tower-http from 0.5.2 to 0.6.6 ([#6030])
- build(deps): bump actions/setup-go from 5 to 6 ([#6013])
- build(deps): bump next from 14.2.28 to 14.2.32 ([#5996])
- build(deps): bump tracing-subscriber from 0.3.19 to 0.3.20 ([#5993])
- build(deps): bump actions/upload-pages-artifact from 3 to 4 ([#5992])
[#6259]: https://github.com/nymtech/nym/pull/6259
[#6253]: https://github.com/nymtech/nym/pull/6253
[#6247]: https://github.com/nymtech/nym/pull/6247
[#6231]: https://github.com/nymtech/nym/pull/6231
[#6227]: https://github.com/nymtech/nym/pull/6227
[#6220]: https://github.com/nymtech/nym/pull/6220
[#6219]: https://github.com/nymtech/nym/pull/6219
[#6216]: https://github.com/nymtech/nym/pull/6216
[#6215]: https://github.com/nymtech/nym/pull/6215
[#6212]: https://github.com/nymtech/nym/pull/6212
[#6207]: https://github.com/nymtech/nym/pull/6207
[#6205]: https://github.com/nymtech/nym/pull/6205
[#6189]: https://github.com/nymtech/nym/pull/6189
[#6181]: https://github.com/nymtech/nym/pull/6181
[#6180]: https://github.com/nymtech/nym/pull/6180
[#6174]: https://github.com/nymtech/nym/pull/6174
[#6144]: https://github.com/nymtech/nym/pull/6144
[#6107]: https://github.com/nymtech/nym/pull/6107
[#6068]: https://github.com/nymtech/nym/pull/6068
[#6063]: https://github.com/nymtech/nym/pull/6063
[#6057]: https://github.com/nymtech/nym/pull/6057
[#6030]: https://github.com/nymtech/nym/pull/6030
[#6013]: https://github.com/nymtech/nym/pull/6013
[#5996]: https://github.com/nymtech/nym/pull/5996
[#5993]: https://github.com/nymtech/nym/pull/5993
[#5992]: https://github.com/nymtech/nym/pull/5992
## [2025.21-mozzarella] (2025-11-25)
- [bugfix] Tunnel not waiting on MixnetClient to shut down cleanly ([#6225])
+686
View File
@@ -0,0 +1,686 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
Nym is a privacy platform that uses mixnet technology to protect against metadata surveillance. The platform consists of several key components:
- Mixnet nodes (mixnodes) for packet mixing
- Gateways (entry/exit points for the network)
- Clients for interacting with the network
- Network monitoring tools
- Validators for network consensus
- Various service providers and integrations
## Build Commands
### Rust Components
```bash
# Default build (debug)
cargo build
# Release build
cargo build --release
# Build a specific package
cargo build -p <package-name>
# Build main components
make build
# Build release versions of main binaries and contracts
make build-release
# Build specific binaries
make build-nym-cli
cargo build -p nym-node --release
cargo build -p nym-api --release
```
### Testing
```bash
# Run clippy, unit tests, and formatting
make test
# Run all tests including slow tests
make test-all
# Run clippy on all workspaces
make clippy
# Run unit tests for a specific package
cargo test -p <package-name>
# Run only expensive/ignored tests
cargo test --workspace -- --ignored
# Run API tests
dotenv -f envs/sandbox.env -- cargo test --test public-api-tests
# Run tests with specific log level
RUST_LOG=debug cargo test -p <package-name>
# Run specific test scripts
./nym-node/tests/test_apis.sh
./scripts/wireguard-exit-policy/exit-policy-tests.sh
```
### Linting and Formatting
```bash
# Run rustfmt on all code
make fmt
# Check formatting without modifying
cargo fmt --all -- --check
# Run clippy with all targets
cargo clippy --workspace --all-targets -- -D warnings
# TypeScript linting
yarn lint
yarn lint:fix
yarn types:lint:fix
# Check dependencies for security/licensing issues
cargo deny check
```
### WASM Components
```bash
# Build all WASM components
make sdk-wasm-build
# Build TypeScript SDK
yarn build:sdk
npx lerna run --scope @nymproject/sdk build --stream
# Build and test WASM components
make sdk-wasm
# Build specific WASM packages
cd wasm/client && make
cd wasm/mix-fetch && make
cd wasm/node-tester && make
```
### Contract Development
```bash
# Build all contracts
make contracts
# Build contracts in release mode
make build-release-contracts
# Generate contract schemas
make contract-schema
# Run wasm-opt on contracts
make wasm-opt-contracts
# Check contracts with cosmwasm-check
make cosmwasm-check-contracts
```
### Running Components
```bash
# Run nym-node as a mixnode
cargo run -p nym-node -- run --mode mixnode
# Run nym-node as a gateway
cargo run -p nym-node -- run --mode gateway
# Run the network monitor
cargo run -p nym-network-monitor
# Run the API server
cargo run -p nym-api
# Run with specific environment
dotenv -f envs/sandbox.env -- cargo run -p nym-api
# Start a local network
./scripts/localnet_start.sh
```
## Architecture
The Nym platform consists of various components organized as a monorepo:
1. **Core Mixnet Infrastructure**:
- `nym-node`: Core binary supporting mixnode and gateway modes
- `common/nymsphinx`: Implementation of the Sphinx packet format
- `common/topology`: Network topology management
- `common/types`: Shared data types across components
2. **Network Monitoring**:
- `nym-network-monitor`: Monitors the network's reliability and performance
- `nym-api`: API server for network stats and monitoring data
- Metrics tracking for nodes, routes, and overall network health
3. **Client Implementations**:
- `clients/native`: Native Rust client implementation
- `clients/socks5`: SOCKS5 proxy client for standard applications
- `wasm`: WebAssembly client implementations (for browsers)
- `nym-connect`: Desktop and mobile clients
4. **Blockchain & Smart Contracts**:
- `common/cosmwasm-smart-contracts`: Smart contract implementations
- `contracts`: CosmWasm contracts for the Nym network
- `common/ledger`: Blockchain integration
5. **Utilities & Tools**:
- `tools`: Various CLI tools and utilities
- `sdk`: SDKs for different languages and platforms
- `documentation`: Documentation generation and management
## Packet System
Nym uses a modified Sphinx packet format for its mixnet:
1. **Message Chunking**:
- Messages are divided into "sets" and "fragments"
- Each fragment fits in a single Sphinx packet
- The `common/nymsphinx/chunking` module handles message fragmentation
2. **Routing**:
- Packets traverse through 3 layers of mixnodes
- Routing information is encrypted in layers (onion routing)
- The final gateway receives and processes the messages
3. **Monitoring**:
- Monitoring system tracks packet delivery through the network
- Routes are analyzed for reliability statistics
- Node performance metrics are collected
## Network Protocol
Nym implements the Loopix mixnet design with several key privacy features:
1. **Continuous-time Mixing**:
- Each mixnode delays messages independently with an exponential distribution
- This creates random reordering of packets, destroying timing correlations
- Offers better anonymity properties than batch mixing approaches
2. **Cover Traffic**:
- Clients and nodes generate dummy "loop" packets that circulate through the network
- These packets are indistinguishable from real traffic
- Creates a baseline level of traffic that hides actual communication patterns
- Provides unobservability (hiding when and how much real traffic is being sent)
3. **Stratified Network Architecture**:
- Traffic flows through Entry Gateway → 3 Mixnode Layers → Exit Gateway
- Path selection is independent per-message (unlike Tor)
- Each node connects only to adjacent layers
4. **Anonymous Replies**:
- Single-Use Reply Blocks (SURBs) allow receiving messages without revealing identity
- Enables bidirectional communication while maintaining privacy
## Network Monitoring Architecture
The network monitoring system is a core component that measures mixnet reliability:
1. The `nym-network-monitor` sends test packets through the network
2. These packets follow predefined routes through multiple mixnodes
3. Metrics are collected about:
- Successful and failed packet deliveries
- Node reliability (percentage of successful packet handling)
- Route reliability (which specific route combinations work best)
4. Results are stored in the database and used by `nym-api` to:
- Present node performance statistics
- Determine network rewards
- Provide route selection guidance to clients
In the current branch, metrics collection is being enhanced with a fanout approach to submit to multiple API endpoints.
## Development Environment
### Required Dependencies
- Rust toolchain (stable, 1.80+)
- Node.js (v20+) and yarn for TypeScript components
- SQLite for local database development
- PostgreSQL for API database (optional, for full API functionality)
- CosmWasm tools for contract development
- For building contracts: `wasm-opt` tool from `binaryen`
- Python 3.8+ for some scripts
- Docker (optional, for containerized development)
- protoc (Protocol Buffers compiler) for some components
### Environment Configurations
The `envs/` directory contains pre-configured environments:
#### Available Environments
- **`local.env`**: Local development environment
- Points to local services (localhost)
- Uses test mnemonics and keys
- Ideal for testing without external dependencies
- **`sandbox.env`**: Sandbox test network
- Public test network with real nodes
- Test tokens available from faucet
- Contract addresses for sandbox deployment
- API: https://sandbox-nym-api1.nymtech.net
- **`mainnet.env`**: Production mainnet
- Real network with real tokens
- Production contract addresses
- API: https://validator.nymtech.net
- Use with caution!
- **`canary.env`**: Canary deployment
- Pre-release testing environment
- Tests new features before mainnet
- **`mainnet-local-api.env`**: Hybrid environment
- Uses mainnet contracts but local API
- Useful for API development against mainnet data
#### Key Environment Variables
```bash
# Network configuration
NETWORK_NAME=sandbox # Network identifier
BECH32_PREFIX=n # Address prefix (n for sandbox, n for mainnet)
NYM_API=https://sandbox-nym-api1.nymtech.net/api
NYXD=https://rpc.sandbox.nymtech.net
NYM_API_NETWORK=sandbox
# Contract addresses (network-specific)
MIXNET_CONTRACT_ADDRESS=n1xr3rq8yvd7qplsw5yx90ftsr2zdhg4e9z60h5duusgxpv72hud3sjkxkav
VESTING_CONTRACT_ADDRESS=n1unyuj8qnmygvzuex3dwmg9yzt9alhvyeat0uu0jedg2wj33efl5qackslz
# ... other contract addresses
# Mnemonic for testing (NEVER use in production)
MNEMONIC="clutch captain shoe salt awake harvest setup primary inmate ugly among become"
# API Keys and tokens
IPINFO_API_TOKEN=your_token_here
AUTHENTICATOR_PASSWORD=password_here
# Logging
RUST_LOG=info # Options: error, warn, info, debug, trace
RUST_BACKTRACE=1 # Enable backtraces
# Database
DATABASE_URL=postgresql://user:pass@localhost/nym_api
```
#### Using Environment Files
```bash
# Load environment and run command
dotenv -f envs/sandbox.env -- cargo run -p nym-api
# Export to shell
source envs/sandbox.env
# Use with make targets
dotenv -f envs/sandbox.env -- make run-api-tests
```
## Initial Setup
### First Time Setup
1. **Install Prerequisites**
```bash
# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Install Node.js and yarn
# Via nvm (recommended):
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
nvm install 20
npm install -g yarn
# Install build tools
# Ubuntu/Debian:
sudo apt-get install build-essential pkg-config libssl-dev protobuf-compiler libpq-dev
# macOS:
brew install protobuf postgresql
# Install wasm-opt for contract builds
npm install -g wasm-opt
# Add wasm target for Rust
rustup target add wasm32-unknown-unknown
```
2. **Clone and Setup Repository**
```bash
git clone https://github.com/nymtech/nym.git
cd nym/nym
# Install JavaScript dependencies
yarn install
# Build the project
make build
```
3. **Database Setup (Optional, for API development)**
```bash
# Install PostgreSQL
# Create database
createdb nym_api
# Run migrations (from nym-api directory)
cd nym-api
sqlx migrate run
```
### Quick Start
```bash
# Run a mixnode locally
dotenv -f envs/sandbox.env -- cargo run -p nym-node -- run --mode mixnode --id my-mixnode
# Run a gateway locally
dotenv -f envs/sandbox.env -- cargo run -p nym-node -- run --mode gateway --id my-gateway
# Run the API server
dotenv -f envs/sandbox.env -- cargo run -p nym-api
# Run a client
cargo run -p nym-client -- init --id my-client
cargo run -p nym-client -- run --id my-client
```
## CI/CD Pipeline
The project uses GitHub Actions for CI/CD with several key workflows:
1. **Build and Test**:
- `ci-build.yml`: Main build workflow for Rust components
- Tests are run on multiple platforms (Linux, Windows, macOS)
- Includes formatting check (rustfmt) and linting (clippy)
2. **Release Process**:
- Binary artifacts are published on release tags
- Multiple platform builds are created
3. **Documentation**:
- Documentation is automatically built and deployed
## Database Structure
The system uses SQLite databases with tables like:
- `mixnode_status`: Status information about mixnodes
- `gateway_status`: Status information about gateways
- `routes`: Route performance information (success/failure of specific paths)
- `monitor_run`: Information about monitoring test runs
## Development Workflows
### Running a Node
To run the mixnode or gateway:
```bash
# Run nym-node as a mixnode with specified identity
cargo run -p nym-node -- run --mode mixnode --id my-mixnode
# Run nym-node as a gateway
cargo run -p nym-node -- run --mode gateway --id my-gateway
```
### Configuration
Nodes can be configured with files in various locations:
- Command-line arguments
- Environment variables
- `.env` files specified with `--config-env-file`
### Monitoring
To monitor the health of your node:
- View logs for real-time information
- Use the node's HTTP API for status information
- Check the explorer for public node statistics
## Common Libraries
- `common/types`: Shared data types across all components
- `common/crypto`: Cryptographic primitives and wrappers
- `common/client-core`: Core client functionality
- `common/gateway-client`: Client-gateway communication
- `common/task`: Task management and concurrency utilities
- `common/nymsphinx`: Sphinx packet implementation for mixnet
- `common/topology`: Network topology management
- `common/credentials`: Credential system for privacy-preserving authentication
- `common/bandwidth-controller`: Bandwidth management and accounting
## Code Conventions
- Error handling: Use anyhow/thiserror for structured error handling
- Logging: Use the tracing framework for logging and diagnostics
- State management: Generally use Tokio/futures for async code
- Configuration: Use the config crate and env vars with defaults
- Database: Use sqlx for type-safe database queries
- Follow clippy recommendations and rustfmt formatting
- Use semantic commit messages: feat, fix, docs, refactor, test, chore
## When Making Changes
- Run `make test` before submitting PRs
- Follow Rust naming conventions
- Use `clippy` to check for common issues
- Update SQLx query caches when modifying DB queries: `cargo sqlx prepare`
- Consider backward compatibility for protocol changes
- Use lefthook pre-commit hooks for TypeScript formatting
- Run `cargo deny check` to verify dependency compliance
- Test against both sandbox and local environments when possible
- Update relevant documentation and CHANGELOG.md
## Development Tools
### Useful Cargo Commands
```bash
# Check for outdated dependencies
cargo outdated
# Analyze binary size
cargo bloat --release -p nym-node
# Generate dependency graph
cargo tree -p nym-api
# Run with instrumentation
cargo run --features profiling -p nym-node
# Check for security advisories
cargo audit
```
### Database Tools
```bash
# SQLx CLI for migrations
cargo install sqlx-cli
# Create new migration
cd nym-api && sqlx migrate add <migration_name>
# Prepare query metadata for offline compilation
cargo sqlx prepare --workspace
# View database schema
./nym-api/enter_db.sh
```
### Development Scripts
- `scripts/build_topology.py`: Generate network topology files
- `scripts/node_api_check.py`: Verify node API endpoints
- `scripts/network_tunnel_manager.sh`: Manage network tunnels
- `scripts/localnet_start.sh`: Start a local test network
- Various deployment scripts in `deployment/` for different environments
## Debugging
- Enable more verbose logging with the RUST_LOG environment variable:
```
RUST_LOG=debug,nym_node=trace cargo run -p nym-node -- run --mode mixnode
```
- Use the HTTP API endpoints for status information
- Check monitoring data in the database for network performance metrics
- For complex issues, use tracing tools to follow packet flow
- Enable backtraces: `RUST_BACKTRACE=full`
- For WASM debugging: Use browser developer tools with source maps
## Deployment and Advanced Configurations
### Deployment Structure
The `deployment/` directory contains Ansible playbooks and configurations for various deployment scenarios:
- **`aws/`**: AWS-specific deployment configurations
- **`mixnode/`**: Mixnode deployment playbooks
- **`gateway/`**: Gateway deployment playbooks
- **`validator/`**: Validator node deployment
- **`sandbox-v2/`**: Complete sandbox environment setup
- **`big-dipper-2/`**: Block explorer deployment
### Sandbox V2 Deployment
The sandbox-v2 deployment (`deployment/sandbox-v2/`) provides a complete test environment:
```bash
# Key playbooks:
- deploy.yaml # Main deployment orchestrator
- deploy-mixnodes.yaml # Deploy mixnodes
- deploy-gateways.yaml # Deploy gateways
- deploy-validators.yaml # Deploy validator nodes
- deploy-nym-api.yaml # Deploy API services
```
### Custom Environment Setup
To create a custom environment:
1. Copy an existing env file: `cp envs/sandbox.env envs/custom.env`
2. Modify the network endpoints and contract addresses
3. Update the `NETWORK_NAME` to your identifier
4. Set appropriate mnemonics and keys (use fresh ones for production!)
### Contract Addresses
Contract addresses are network-specific and defined in environment files:
- Mixnet contract: Manages mixnode/gateway registry
- Vesting contract: Handles token vesting schedules
- Coconut contracts: Privacy-preserving credentials
- Name service: Human-readable address mapping
- Ecash contract: Electronic cash functionality
### Local Network Setup
For a completely local network:
```bash
# Start local chain
./scripts/localnet_start.sh
# Deploy contracts
cd contracts
make deploy-local
# Start nodes with local config
dotenv -f envs/local.env -- cargo run -p nym-node -- run --mode mixnode
```
## Common Issues and Troubleshooting
### Database Issues
- When modifying database queries, you must update SQLx query caches:
```bash
cargo sqlx prepare
```
- If you see SQLx errors about missing query files, this is likely the cause
- For "database is locked" errors with SQLite, ensure only one process accesses the DB
- For PostgreSQL connection issues, verify DATABASE_URL and that the server is running
### API Connection Issues
- Check the environment variables pointing to the APIs (NYM_API, NYXD)
- Verify network connectivity and API health endpoints
- For authentication issues, check node keys and credentials
- Common endpoints to verify:
- API health: `$NYM_API/health`
- Chain status: `$NYXD/status`
- Contract info: `$NYXD/cosmwasm/wasm/v1/contract/$CONTRACT_ADDRESS`
### Build Problems
- Clean dependencies with `cargo clean` for a fresh build
- Check for compatible Rust version (1.80+ recommended)
- For smart contract builds, ensure wasm-opt is installed: `npm install -g wasm-opt`
- For cross-compilation issues, check target-specific dependencies
- WASM build issues: Ensure wasm32-unknown-unknown target is installed:
```bash
rustup target add wasm32-unknown-unknown
```
- For "cannot find -lpq" errors, install PostgreSQL development files:
```bash
# Ubuntu/Debian
sudo apt-get install libpq-dev
# macOS
brew install postgresql
```
### Environment Issues
- Contract address mismatches: Ensure you're using the correct environment file
- "Account sequence mismatch": The account nonce is out of sync, wait and retry
- Token decimal issues: Sandbox uses different decimal places than mainnet
- API version mismatches: Ensure your local API version matches the network
- "Insufficient funds": Get test tokens from faucet (sandbox) or check balance
- Gateway/mixnode bonding issues: Verify minimum stake requirements
## Working with Routes and Monitoring
1. Route monitoring metrics are stored in a `routes` table with:
- Layer node IDs (layer1, layer2, layer3, gw)
- Success flag (boolean)
- Timestamp
2. To analyze routes:
- Check `NetworkAccount` and `AccountingRoute` in `nym-network-monitor/src/accounting.rs`
- View monitoring logic in `common/nymsphinx/chunking/monitoring.rs`
- Observe how routes are submitted to the database in the `submit_accounting_routes_to_db` function
## Performance Optimization
### Profiling and Benchmarking
```bash
# Run benchmarks
cargo bench -p nym-node
# Profile with perf (Linux)
cargo build --release --features profiling
perf record --call-graph=dwarf ./target/release/nym-node run --mode mixnode
perf report
# Generate flamegraph
cargo install flamegraph
cargo flamegraph --bin nym-node -- run --mode mixnode
```
### Common Performance Considerations
- Use bounded channels for backpressure
- Batch database operations where possible
- Monitor memory usage with `RUST_LOG=nym_node::metrics=debug`
- Use connection pooling for database connections
- Consider using `jemalloc` for better memory allocation performance
Generated
+1203 -2139
View File
File diff suppressed because it is too large Load Diff
+11 -126
View File
@@ -72,10 +72,6 @@ members = [
"common/nym-cache",
"common/nym-connection-monitor",
"common/nym-id",
"common/nym-kcp",
"common/nym-lp",
"common/nym-lp-common",
"common/nym-kkt",
"common/nym-metrics",
"common/nym_offline_compact_ecash",
"common/nymnoise",
@@ -152,19 +148,18 @@ members = [
"service-providers/common",
"service-providers/ip-packet-router",
"service-providers/network-requester",
"nym-sqlx-pool-guard",
"sqlx-pool-guard",
"tools/echo-server",
"tools/internal/contract-state-importer/importer-cli",
"tools/internal/contract-state-importer/importer-contract",
"tools/internal/mixnet-connectivity-check",
# "tools/internal/sdk-version-bump",
# "tools/internal/sdk-version-bump",
"tools/internal/ssl-inject",
"tools/internal/testnet-manager",
"tools/internal/testnet-manager/dkg-bypass-contract",
"tools/internal/validator-status-check",
"tools/nym-cli",
"tools/nym-id-cli",
"tools/nym-lp-client",
"tools/nym-nr-query",
"tools/nymvisor",
"tools/ts-rs-cli",
@@ -173,8 +168,7 @@ members = [
"wasm/mix-fetch",
"wasm/node-tester",
"wasm/zknym-lib",
"nym-gateway-probe",
"integration-tests", "common/nym-lp-transport", "common/nym-kkt-ciphersuite",
"nym-gateway-probe"
]
default-members = [
@@ -192,7 +186,6 @@ default-members = [
"service-providers/ip-packet-router",
"service-providers/network-requester",
"tools/nymvisor",
"nym-registration-client"
]
exclude = ["contracts", "nym-wallet", "cpu-cycles"]
@@ -206,7 +199,6 @@ edition = "2024"
license = "Apache-2.0"
rust-version = "1.85"
readme = "README.md"
version = "1.20.1"
[workspace.dependencies]
addr = "0.15.6"
@@ -215,7 +207,6 @@ aes = "0.8.1"
aes-gcm = "0.10.1"
aes-gcm-siv = "0.11.1"
ammonia = "4"
ansi_term = "0.12"
anyhow = "1.0.98"
arc-swap = "1.7.1"
argon2 = "0.5.0"
@@ -255,9 +246,9 @@ criterion = "0.5"
csv = "1.3.1"
ctr = "0.9.1"
cupid = "0.6.1"
curve25519-dalek = "4.1.3"
dashmap = "5.5.3"
defguard_wireguard_rs = "0.8.0"
# We want https://github.com/DefGuard/wireguard-rs/pull/64 , but there's no crates.io release being pushed out anymore
defguard_wireguard_rs = { git = "https://github.com/DefGuard/wireguard-rs.git", rev = "v0.4.7" }
digest = "0.10.7"
dirs = "6.0"
dotenvy = "0.15.6"
@@ -295,9 +286,7 @@ inventory = "0.3.21"
ip_network = "0.4.1"
ipnetwork = "0.20"
itertools = "0.14.0"
jwt-simple = { version = "0.12.12", default-features = false, features = [
"pure-rust",
] }
jwt-simple = { version = "0.12.12", default-features = false, features = ["pure-rust"] }
k256 = "0.13"
lazy_static = "1.5.0"
ledger-transport = "0.10.0"
@@ -305,9 +294,8 @@ ledger-transport-hid = "0.10.0"
log = "0.4"
mime = "0.3.17"
moka = { version = "0.12", features = ["future"] }
nix = "0.30.1"
nix = "0.27.1"
notify = "5.1.0"
num_enum = "0.7.5"
once_cell = "1.21.3"
opentelemetry = "0.19.0"
opentelemetry-jaeger = "0.18.0"
@@ -338,7 +326,7 @@ serde_repr = "0.1"
serde_with = "3.9.0"
serde_yaml = "0.9.25"
serde_plain = "1.0.2"
sha2 = "0.10.3"
sha2 = "0.10.9"
si-scale = "0.2.3"
snow = "0.9.6"
sphinx-packet = "=0.6.0"
@@ -354,7 +342,6 @@ test-with = { version = "0.15.4", default-features = false }
tempfile = "3.20"
thiserror = "2.0"
time = "0.3.41"
tls_codec = "0.4.1"
tokio = "1.47"
tokio-postgres = "0.7"
tokio-stream = "0.1.17"
@@ -390,113 +377,11 @@ zeroize = "1.7.0"
prometheus = { version = "0.14.0" }
# Workspace dep definitions required by crates.io publication - we need a workspace version since `cargo workspaces` doesn't work with path imports from crate manifests
nym-api-requests = { version = "1.20.1", path = "nym-api/nym-api-requests" }
nym-authenticator-requests = { version = "1.20.1", path = "common/authenticator-requests" }
nym-async-file-watcher = { version = "1.20.1", path = "common/async-file-watcher" }
nym-authenticator-client = { version = "1.20.1", path = "nym-authenticator-client" }
nym-bandwidth-controller = { version = "1.20.1", path = "common/bandwidth-controller" }
nym-bin-common = { version = "1.20.1", path = "common/bin-common" }
nym-cache = { version = "1.20.1", path = "common/nym-cache" }
nym-client-core = { version = "1.20.1", path = "common/client-core", default-features = false }
nym-client-core-config-types = { version = "1.20.1", path = "common/client-core/config-types" }
nym-client-core-gateways-storage = { version = "1.20.1", path = "common/client-core/gateways-storage" }
nym-client-core-surb-storage = { version = "1.20.1", path = "common/client-core/surb-storage" }
nym-client-websocket-requests = { version = "1.20.1", path = "clients/native/websocket-requests" }
nym-common = { version = "1.20.1", path = "common/nym-common" }
nym-compact-ecash = { version = "1.20.1", path = "common/nym_offline_compact_ecash" }
nym-config = { version = "1.20.1", path = "common/config" }
nym-contracts-common = { version = "1.20.1", path = "common/cosmwasm-smart-contracts/contracts-common" }
nym-coconut-dkg-common = { version = "1.20.1", path = "common/cosmwasm-smart-contracts/coconut-dkg" }
nym-credential-storage = { version = "1.20.1", path = "common/credential-storage" }
nym-credential-utils = { version = "1.20.1", path = "common/credential-utils" }
nym-credential-proxy-lib = { version = "1.20.1", path = "common/credential-proxy" }
nym-credentials = { version = "1.20.1", path = "common/credentials", default-features = false }
nym-credentials-interface = { version = "1.20.1", path = "common/credentials-interface" }
nym-credential-proxy-requests = { version = "1.20.1", path = "nym-credential-proxy/nym-credential-proxy-requests", default-features = false }
nym-credential-verification = { version = "1.20.1", path = "common/credential-verification" }
nym-crypto = { version = "1.20.1", path = "common/crypto", default-features = false }
nym-dkg = { version = "1.20.1", path = "common/dkg" }
nym-ecash-contract-common = { version = "1.20.1", path = "common/cosmwasm-smart-contracts/ecash-contract" }
nym-ecash-signer-check = { version = "1.20.1", path = "common/ecash-signer-check" }
nym-ecash-signer-check-types = { version = "1.20.1", path = "common/ecash-signer-check-types" }
nym-ecash-time = { version = "1.20.1", path = "common/ecash-time" }
nym-exit-policy = { version = "1.20.1", path = "common/exit-policy" }
nym-ffi-shared = { version = "1.20.1", path = "sdk/ffi/shared" }
nym-gateway-client = { version = "1.20.1", path = "common/client-libs/gateway-client", default-features = false }
nym-gateway-requests = { version = "1.20.1", path = "common/gateway-requests" }
nym-gateway-storage = { version = "1.20.1", path = "common/gateway-storage" }
nym-gateway-stats-storage = { version = "1.20.1", path = "common/gateway-stats-storage" }
nym-group-contract-common = { version = "1.20.1", path = "common/cosmwasm-smart-contracts/group-contract" }
nym-http-api-client = { version = "1.20.1", path = "common/http-api-client" }
nym-http-api-client-macro = { version = "1.20.1", path = "common/http-api-client-macro" }
nym-http-api-common = { version = "1.20.1", path = "common/http-api-common", default-features = false }
nym-id = { version = "1.20.1", path = "common/nym-id" }
nym-kkt-ciphersuite = { path = "common/nym-kkt-ciphersuite" }
nym-ip-packet-client = { version = "1.20.1", path = "nym-ip-packet-client" }
nym-ip-packet-requests = { version = "1.20.1", path = "common/ip-packet-requests" }
nym-metrics = { version = "1.20.1", path = "common/nym-metrics" }
nym-mixnet-client = { version = "1.20.1", path = "common/client-libs/mixnet-client" }
nym-mixnet-contract-common = { version = "1.20.1", path = "common/cosmwasm-smart-contracts/mixnet-contract" }
nym-multisig-contract-common = { version = "1.20.1", path = "common/cosmwasm-smart-contracts/multisig-contract" }
nym-network-defaults = { version = "1.20.1", path = "common/network-defaults" }
nym-node-tester-utils = { version = "1.20.1", path = "common/node-tester-utils" }
nym-noise = { version = "1.20.1", path = "common/nymnoise" }
nym-noise-keys = { version = "1.20.1", path = "common/nymnoise/keys" }
nym-nonexhaustive-delayqueue = { version = "1.20.1", path = "common/nonexhaustive-delayqueue" }
nym-node-requests = { version = "1.20.1", path = "nym-node/nym-node-requests", default-features = false }
nym-node-metrics = { version = "1.20.1", path = "nym-node/nym-node-metrics" }
nym-ordered-buffer = { version = "1.20.1", path = "common/socks5/ordered-buffer" }
nym-outfox = { version = "1.20.1", path = "nym-outfox" }
nym-registration-common = { version = "1.20.1", path = "common/registration" }
nym-pemstore = { version = "1.20.1", path = "common/pemstore" }
nym-performance-contract-common = { version = "1.20.1", path = "common/cosmwasm-smart-contracts/nym-performance-contract" }
nym-sdk = { version = "1.20.1", path = "sdk/rust/nym-sdk" }
nym-serde-helpers = { version = "1.20.1", path = "common/serde-helpers" }
nym-service-providers-common = { version = "1.20.1", path = "service-providers/common" }
nym-service-provider-requests-common = { version = "1.20.1", path = "common/service-provider-requests-common" }
nym-socks5-client-core = { version = "1.20.1", path = "common/socks5-client-core" }
nym-socks5-proxy-helpers = { version = "1.20.1", path = "common/socks5/proxy-helpers" }
nym-socks5-requests = { version = "1.20.1", path = "common/socks5/requests" }
nym-sphinx = { version = "1.20.1", path = "common/nymsphinx" }
nym-sphinx-acknowledgements = { version = "1.20.1", path = "common/nymsphinx/acknowledgements" }
nym-sphinx-addressing = { version = "1.20.1", path = "common/nymsphinx/addressing" }
nym-sphinx-anonymous-replies = { version = "1.20.1", path = "common/nymsphinx/anonymous-replies" }
nym-sphinx-chunking = { version = "1.20.1", path = "common/nymsphinx/chunking" }
nym-sphinx-cover = { version = "1.20.1", path = "common/nymsphinx/cover" }
nym-sphinx-forwarding = { version = "1.20.1", path = "common/nymsphinx/forwarding" }
nym-sphinx-framing = { version = "1.20.1", path = "common/nymsphinx/framing" }
nym-sphinx-params = { version = "1.20.1", path = "common/nymsphinx/params" }
nym-sphinx-routing = { version = "1.20.1", path = "common/nymsphinx/routing" }
nym-sphinx-types = { version = "1.20.1", path = "common/nymsphinx/types" }
nym-statistics-common = { version = "1.20.1", path = "common/statistics" }
nym-store-cipher = { version = "1.20.1", path = "common/store-cipher" }
nym-task = { version = "1.20.1", path = "common/task" }
nym-tun = { version = "1.20.1", path = "common/tun" }
nym-test-utils = { version = "1.20.1", path = "common/test-utils" }
nym-ticketbooks-merkle = { version = "1.20.1", path = "common/ticketbooks-merkle" }
nym-topology = { version = "1.20.1", path = "common/topology" }
nym-types = { version = "1.20.1", path = "common/types" }
nym-upgrade-mode-check = { version = "1.20.1", path = "common/upgrade-mode-check" }
nym-validator-client = { version = "1.20.1", path = "common/client-libs/validator-client", default-features = false }
nym-vesting-contract-common = { version = "1.20.1", path = "common/cosmwasm-smart-contracts/vesting-contract" }
nym-verloc = { version = "1.20.1", path = "common/verloc" }
nym-wireguard = { version = "1.20.1", path = "common/wireguard" }
nym-wireguard-types = { version = "1.20.1", path = "common/wireguard-types" }
nym-wireguard-private-metadata-shared = { version = "1.20.1", path = "common/wireguard-private-metadata/shared" }
nym-wireguard-private-metadata-client = { version = "1.20.1", path = "common/wireguard-private-metadata/client" }
nym-wireguard-private-metadata-server = { version = "1.20.1", path = "common/wireguard-private-metadata/server" }
nym-sqlx-pool-guard = { version = "1.2.0", path = "nym-sqlx-pool-guard" }
nym-wasm-client-core = { version = "1.20.1", path = "common/wasm/client-core" }
nym-wasm-storage = { version = "1.20.1", path = "common/wasm/storage" }
nym-wasm-utils = { version = "1.20.1", path = "common/wasm/utils", default-features = false }
nyxd-scraper-shared = { version = "1.20.1", path = "common/nyxd-scraper-shared" }
# coconut/DKG related
# unfortunately until https://github.com/zkcrypto/nym-bls12_381-fork/issues/10 is resolved, we have to rely on the fork
# unfortunately until https://github.com/zkcrypto/bls12_381/issues/10 is resolved, we have to rely on the fork
# as we need to be able to serialize Gt so that we could create the lookup table for baby-step-giant-step algorithm
# plus to make our live easier we need serde support from https://github.com/zkcrypto/nym-bls12_381-fork/pull/125
nym-bls12_381-fork = { version = "0.8.0-forked", default-features = false }
# plus to make our live easier we need serde support from https://github.com/zkcrypto/bls12_381/pull/125
bls12_381 = { git = "https://github.com/jstuczyn/bls12_381", default-features = false, branch = "temp/experimental-serdect-updated" }
group = { version = "0.13.0", default-features = false }
ff = { version = "0.13.1", default-features = false }
subtle = "2.5.0"
+10 -10
View File
@@ -2,7 +2,7 @@
ansible_ssh_private_key_file: ~/.ssh/<SSH_KEY>
# nym_version: "v2025.21-mozzarella"
#
#
# NOTE:
# if you want to pin Nym to a specific version instead of using the
# latest release from GitHub in /tasks/main.yml then
@@ -13,17 +13,17 @@ tunnel_manager_url: "https://github.com/nymtech/nym/raw/refs/heads/develop/scrip
quic_bridge_deployment_url: "https://raw.githubusercontent.com/nymtech/nym/refs/heads/develop/scripts/nym-node-setup/quic_bridge_deployment.sh"
# NOTE: These values will be used globally unless overwritten per node in inventory/all
ansible_user: root # used for ssh, like `ssh root@nym-exit.ch-1.mynodes.net`
email: "<EMAIL>" # used in certbot, description.toml and landing page
website: "<WEBSITE>" # it is used in the description.toml
description: "<NODE_PUBLIC_DESCRIPTION>" # or define per node in inventory/all
ansible_user: root # used for ssh, like `ssh root@nym-exit.ch-1.mynodes.net`
email: "<EMAIL>" # used in certbot, description.toml and landing page
website: "<WEBSITE>" # it is used in the description.toml
description: "<NODE_PUBLIC_DESCRIPTION>" # or define per node in inventory/all
# NOTE: Set these vars if you want them globally for all nodes
# Per node changes in inventory/all will overwrite these global ones:
hostname: "" # this is a fallback, keep it and setup hostname per node in inventory/all
# moniker: "<MONIKER>" # if not setup here not in inventory/all it get's derived from the hostname
# mode: <MODE> # entry-gateway/exit-gateway/mixnode
# wireguard_enabled: <WIREGUARD_ENABLED> # true/false
hostname: "" # this is a fallback, keep it and setup hostname per node in inventory/all
# moniker: "<MONIKER>" # if not setup here not in inventory/all it get's derived from the hostname
# mode: <MODE> # entry-gateway/exit-gateway/mixnode
# wireguard_enabled: <WIREGUARD_ENABLED> # true/false
# NOTE: Possible vars to incule on landing page, etc.
# operator_name: "<OPERATOR_NAME>"
@@ -41,4 +41,4 @@ packages:
- ca-certificates
- jq
- wget
- ufw
- ufw
+3 -4
View File
@@ -1,10 +1,9 @@
---
- name: Set hostname
hostname:
name: "{{ hostname }}"
when: hostname is defined and hostname | length > 0
- name: Install aptitude
- name: Install aptitude
apt:
name: aptitude
update_cache: yes
@@ -15,9 +14,9 @@
apt:
update_cache: yes
upgrade: yes
- name: Install essential packages
package:
name: "{{ packages }}"
state: latest
update_cache: yes
update_cache: yes
@@ -1,10 +0,0 @@
---
- name: Reload nginx
service:
name: nginx
state: reloaded
- name: Restart nginx
service:
name: nginx
state: restarted
+14 -126
View File
@@ -1,4 +1,3 @@
---
- name: Install nginx and certbot
apt:
name:
@@ -6,168 +5,57 @@
- certbot
- python3-certbot-nginx
state: present
update_cache: yes
- name: Ensure nginx snippets directory exists
file:
path: /etc/nginx/snippets
state: directory
mode: "0755"
# own SSL defaults - don't rely on certbot files
- name: Install Nym SSL options snippet
copy:
dest: /etc/nginx/snippets/nym-ssl-options.conf
mode: "0644"
content: |
ssl_session_cache shared:NYMSSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
# Reasonable modern cipher set (works across Ubuntu nginx builds)
ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305";
# OCSP stapling is nice but can break if resolver isn't set; keep minimal here.
notify: Restart nginx
- name: Ensure web root directory exists
- name: Create web root directory
file:
path: "/var/www/{{ hostname }}"
state: directory
mode: "0755"
- name: Deploy landing page
- name: Create landing page template
tags: landing
template:
src: landing.html.j2
dest: "/var/www/{{ hostname }}/index.html"
mode: "0644"
notify: Restart nginx
# remove default site - safe on fresh + redeploy
- name: Disable default nginx site symlink
- name: Remove default nginx site
file:
path: /etc/nginx/sites-enabled/default
state: absent
notify: Restart nginx
- name: Remove default nginx site definition if present
file:
path: /etc/nginx/sites-available/default
state: absent
notify: Restart nginx
# always deploy/enable HTTP vhost
- name: Deploy HTTP vhost
- name: Add bare-bones nginx template
template:
src: nginx-site.conf.j2
dest: "/etc/nginx/sites-available/{{ hostname }}"
mode: "0644"
notify: Restart nginx
- name: Enable HTTP vhost (force correct symlink)
- name: Enable nginx config
file:
src: "/etc/nginx/sites-available/{{ hostname }}"
dest: "/etc/nginx/sites-enabled/{{ hostname }}"
state: link
force: true
notify: Restart nginx
# detect if cert exists already
- name: Check whether certificate exists
stat:
path: "/etc/letsencrypt/live/{{ hostname }}/fullchain.pem"
register: le_cert
# if cert does NOT exist yet, ensure SSL/WSS are NOT enabled
- name: Ensure SSL and WSS vhosts are disabled until cert exists
file:
path: "{{ item }}"
state: absent
loop:
- "/etc/nginx/sites-enabled/{{ hostname }}-ssl"
- "/etc/nginx/sites-enabled/nym-wss-config"
when: not le_cert.stat.exists
notify: Restart nginx
- name: Ensure nginx is enabled and running (needed for ACME http-01)
service:
name: nginx
state: started
enabled: yes
- name: Validate nginx configuration (HTTP stage)
- name: Validate nginx configuration
command: nginx -t
changed_when: false
- name: Flush handlers (ensure HTTP is active before certbot)
meta: flush_handlers
# certbot strategy:
# - if cert exists: webroot - doesn't touch nginx
# - else: --nginx works first-time; may touch nginx
- name: Obtain/renew certificate
- name: Obtain SSL certificate
command:
cmd: >-
{% if le_cert.stat.exists %}
certbot certonly --webroot
-w /var/www/{{ hostname }}
--non-interactive --agree-tos --keep-until-expiring
-m {{ email }} -d {{ hostname }}
{% else %}
certbot --nginx
--non-interactive --agree-tos --redirect
-m {{ email }} -d {{ hostname }}
{% endif %}
register: certbot_result
failed_when: false
cmd: "certbot --nginx --non-interactive --agree-tos --redirect -m {{ email }} -d {{ hostname }}"
# re-check cert after certbot attempt
- name: Re-check whether certificate exists after certbot
stat:
path: "/etc/letsencrypt/live/{{ hostname }}/fullchain.pem"
register: le_cert_after
# only deploy/enable SSL & WSS if cert exists
- name: Deploy HTTPS vhost for {{ hostname }}
template:
src: nginx-site-ssl.conf.j2
dest: "/etc/nginx/sites-available/{{ hostname }}-ssl"
mode: "0644"
when: le_cert_after.stat.exists
notify: Restart nginx
- name: Enable HTTPS vhost (force correct symlink)
file:
src: "/etc/nginx/sites-available/{{ hostname }}-ssl"
dest: "/etc/nginx/sites-enabled/{{ hostname }}-ssl"
state: link
force: true
when: le_cert_after.stat.exists
notify: Restart nginx
- name: Deploy WSS vhost
- name: Add wss config from nginx template
template:
src: wss-config.conf.j2
dest: "/etc/nginx/sites-available/nym-wss-config"
mode: "0644"
when: le_cert_after.stat.exists
notify: Restart nginx
- name: Enable WSS vhost (force correct symlink)
- name: Enable WSS config
file:
src: "/etc/nginx/sites-available/nym-wss-config"
dest: "/etc/nginx/sites-enabled/nym-wss-config"
state: link
force: true
when: le_cert_after.stat.exists
notify: Restart nginx
- name: Validate nginx configuration (final)
- name: Validate nginx config after wss
command: nginx -t
changed_when: false
- name: Flush handlers (apply restart after successful tests)
meta: flush_handlers
- name: Restart nginx to apply changes
service: name=nginx state=restarted enabled=yes
@@ -1,17 +0,0 @@
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name {{ hostname }};
ssl_certificate /etc/letsencrypt/live/{{ hostname }}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{{ hostname }}/privkey.pem;
include /etc/nginx/snippets/nym-ssl-options.conf;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
@@ -4,15 +4,10 @@ server {
server_name {{ hostname }};
root /var/www/{{ hostname }};
index index.html;
location ^~ /.well-known/acme-challenge/ {
default_type "text/plain";
try_files $uri =404;
}
location / {
return 301 https://$host$request_uri;
proxy_pass http://127.0.0.1:8080;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
@@ -4,9 +4,10 @@ server {
server_name {{ hostname }};
ssl_certificate /etc/letsencrypt/live/{{ hostname }}/fullchain.pem;
ssl_certificate /etc/letsencrypt/live/{{ hostname }}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{{ hostname }}/privkey.pem;
include /etc/nginx/snippets/nym-ssl-options.conf;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
+5 -1
View File
@@ -6,6 +6,10 @@ nym_install_dir: /root/nym-binaries
http_bind_address: "0.0.0.0:8080" # maps to --http-bind-address
mixnet_bind_address: "0.0.0.0:1789" # maps to --mixnet-bind-address
# WireGuard boolean
wireguard_enabled: "{{ wireguard_enabled | default(false) | bool }}"
# Landing page base dir, hostname is appended in the task
landing_page_assets_base_dir: "/var/www"
@@ -33,4 +37,4 @@ nym_ufw_rules:
- { port: 8080, proto: tcp }
- { port: 9000, proto: tcp }
- { port: 9001, proto: tcp }
- { port: 51822, proto: udp }
- { port: 51822, proto: udp }
@@ -1,4 +1,3 @@
---
- name: Reload systemd
systemd:
daemon_reload: yes
+3 -3
View File
@@ -1,5 +1,5 @@
---
# useful when the host is behind a NAT
# Useful when the host is behind a NAT
- name: Fetch the public IP address
command: "curl -4 canhazip.com"
register: ipv4
@@ -11,7 +11,7 @@
public_ip: "{{ ipv4.stdout | default(ansible_default_ipv4.address) }}"
- name: Initialize nym node
# delete the part from --hostname onward if you run mode=mixnode only
# Delete the part from --hostname onward if you run mode=mixnode only
command:
cmd: >
{{ nym_install_dir }}/nym-node run
@@ -25,7 +25,7 @@
{{ nym_extra_flags }}
--hostname {{ hostname }}
--wireguard-enabled {{ (wireguard_enabled | default('false') | bool) | ternary('true','false') }}
--wireguard-enabled {{ wireguard_enabled }}
--landing-page-assets-path {{ landing_page_assets_base_dir }}/{{ hostname }}/
{% if nym_write_flag %}-w{% endif %}
{% if nym_init_only_flag %}--init-only{% endif %}
+1 -11
View File
@@ -1,12 +1,3 @@
---
- name: Ensure UFW is installed
apt:
name: ufw
state: present
update_cache: yes
when: nym_ufw_enable
- name: Configure UFW rules
ufw:
rule: allow
@@ -23,10 +14,9 @@
- name: Allow bandwidth/topup rule inside WG tunnel
command: >
ufw allow in on nymwg to any port 51830 proto tcp comment 'bandwidth queries/topup'
changed_when: false
when:
- nym_ufw_enable
- (wireguard_enabled | default(false) | bool)
- (wireguard_enabled | bool)
- name: Enable UFW
ufw:
@@ -6,10 +6,10 @@ StartLimitBurst=10
[Service]
User={{ ansible_user }}
LimitNOFILE=65536
ExecStart=/root/nym-binaries/nym-node run --mode {{ mode }} --accept-operator-terms-and-conditions --wireguard-enabled {{ (wireguard_enabled | default(false) | bool) | ternary('true','false') }}
ExecStart=/root/nym-binaries/nym-node run --mode {{ mode }} --accept-operator-terms-and-conditions --wireguard-enabled {{ wireguard_enabled }}
KillSignal=SIGINT
Restart=on-failure
RestartSec=30
[Install]
WantedBy=multi-user.target
WantedBy=multi-user.target
+9 -6
View File
@@ -1,11 +1,14 @@
---
- name: Download network-tunnel-manager.sh
tags: network tunnel manager
get_url:
url: "{{ tunnel_manager_url }}"
dest: "/root/nym-binaries/network-tunnel-manager.sh"
mode: "0755"
- name: Configure tunnel manager
tags:
- network_tunnel_manager
tags: network tunnel manager
become: true
command:
cmd: "/root/nym-binaries/network-tunnel-manager.sh {{ item }}"
loop:
- complete_networking_configuration
register: tunnel_mgr
failed_when: false
- complete_networking_configuration
@@ -9,7 +9,7 @@
changed_when: false
when: not ansible_check_mode
# show the full stdout
# show the full stdout so we dont depend on regex parsing at all
# show full upgraded version output, line by line
- name: Show upgraded nym-node version info
debug:
@@ -116,7 +116,7 @@
when: not ansible_check_mode and (upgrade_ok | default(false)) == false
# optional: hard-fail the play for CI environments
#- name: fail the play to signal upgrade failure
#- name: Fail the play to signal upgrade failure
# fail:
# msg: "nym-node upgrade failed; rolled back to previous binary."
# when: not ansible_check_mode and (upgrade_ok | default(false)) == false
+17 -18
View File
@@ -1,12 +1,11 @@
[package]
name = "nym-client"
version = "1.1.69"
version = "1.1.67"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
description = "Implementation of the Nym Client"
edition = "2021"
rust-version = "1.85"
license.workspace = true
publish = false
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -43,32 +42,32 @@ tokio-tungstenite = { workspace = true }
zeroize = { workspace = true }
## internal
nym-bandwidth-controller = { workspace = true }
nym-bin-common = { workspace = true, features = [
nym-bandwidth-controller = { path = "../../common/bandwidth-controller" }
nym-bin-common = { path = "../../common/bin-common", features = [
"output_format",
"clap",
"basic_tracing",
] }
nym-client-core = { workspace = true, features = [
nym-client-core = { path = "../../common/client-core", features = [
"fs-credentials-storage",
"fs-surb-storage",
"fs-gateways-storage",
"cli",
] }
nym-config = { workspace = true }
nym-credential-storage = { workspace = true }
nym-credentials = { workspace = true }
nym-crypto = { workspace = true }
nym-gateway-requests = { workspace = true }
nym-network-defaults = { workspace = true }
nym-sphinx = { workspace = true }
nym-pemstore = { workspace = true }
nym-task = { workspace = true }
nym-topology = { workspace = true }
nym-validator-client = { workspace = true, features = [
nym-config = { path = "../../common/config" }
nym-credential-storage = { path = "../../common/credential-storage" }
nym-credentials = { path = "../../common/credentials" }
nym-crypto = { path = "../../common/crypto" }
nym-gateway-requests = { path = "../../common/gateway-requests" }
nym-network-defaults = { path = "../../common/network-defaults" }
nym-sphinx = { path = "../../common/nymsphinx" }
nym-pemstore = { path = "../../common/pemstore" }
nym-task = { path = "../../common/task" }
nym-topology = { path = "../../common/topology" }
nym-validator-client = { path = "../../common/client-libs/validator-client", features = [
"http-client",
] }
nym-client-websocket-requests = { workspace = true }
nym-id = { workspace = true }
nym-client-websocket-requests = { path = "websocket-requests" }
nym-id = { path = "../../common/nym-id" }
[dev-dependencies]
+2 -6
View File
@@ -1,13 +1,9 @@
[package]
name = "nym-client-websocket-requests"
version.workspace = true
version = "0.1.0"
authors = ["Jędrzej Stuczyński <andrew@nymtech.net>"]
edition = "2021"
license.workspace = true
description = "Request and response definitions for Nym client websocket connections"
repository.workspace = true
homepage.workspace = true
documentation.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -15,4 +11,4 @@ documentation.workspace = true
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
nym-sphinx = { workspace = true }
nym-sphinx = { path = "../../../common/nymsphinx" }
+16 -17
View File
@@ -1,12 +1,11 @@
[package]
name = "nym-socks5-client"
version = "1.1.69"
version = "1.1.67"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address"
edition = "2021"
rust-version = "1.85"
license.workspace = true
publish = false
[dependencies]
bs58 = { workspace = true }
@@ -25,30 +24,30 @@ url = { workspace = true }
zeroize = { workspace = true }
# internal
nym-bin-common = { workspace = true, features = [
nym-bin-common = { path = "../../common/bin-common", features = [
"output_format",
"clap",
"basic_tracing",
] }
nym-client-core = { workspace = true, features = [
nym-client-core = { path = "../../common/client-core", features = [
"fs-credentials-storage",
"fs-surb-storage",
"fs-gateways-storage",
"cli",
] }
nym-config = { workspace = true }
nym-credential-storage = { workspace = true }
nym-credentials = { workspace = true }
nym-crypto = { workspace = true }
nym-gateway-requests = { workspace = true }
nym-id = { workspace = true }
nym-network-defaults = { workspace = true }
nym-ordered-buffer = { workspace = true }
nym-pemstore = { workspace = true }
nym-socks5-client-core = { workspace = true }
nym-sphinx = { workspace = true }
nym-topology = { workspace = true }
nym-validator-client = { workspace = true, features = [
nym-config = { path = "../../common/config" }
nym-credential-storage = { path = "../../common/credential-storage" }
nym-credentials = { path = "../../common/credentials" }
nym-crypto = { path = "../../common/crypto" }
nym-gateway-requests = { path = "../../common/gateway-requests" }
nym-id = { path = "../../common/nym-id" }
nym-network-defaults = { path = "../../common/network-defaults" }
nym-ordered-buffer = { path = "../../common/socks5/ordered-buffer" }
nym-pemstore = { path = "../../common/pemstore" }
nym-socks5-client-core = { path = "../../common/socks5-client-core" }
nym-sphinx = { path = "../../common/nymsphinx" }
nym-topology = { path = "../../common/topology" }
nym-validator-client = { path = "../../common/client-libs/validator-client", features = [
"http-client",
] }
+1 -5
View File
@@ -1,12 +1,8 @@
[package]
name = "nym-async-file-watcher"
version.workspace = true
version = "0.1.0"
edition.workspace = true
license.workspace = true
description = "Simple file watcher that sends a notification whenever there was any change in the watched file"
repository.workspace = true
homepage.workspace = true
documentation.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+9 -10
View File
@@ -1,13 +1,12 @@
[package]
name = "nym-authenticator-requests"
version.workspace = true
version = "0.1.0"
authors.workspace = true
repository.workspace = true
homepage.workspace = true
documentation.workspace = true
edition.workspace = true
license.workspace = true
description = "Crate defining requests and responses for the Nym authenticator client"
[dependencies]
base64 = { workspace = true }
@@ -19,12 +18,12 @@ strum_macros = { workspace = true }
thiserror = { workspace = true }
tracing = { workspace = true }
nym-credentials-interface = { workspace = true }
nym-crypto = { workspace = true, features = ["asymmetric"] }
nym-network-defaults = { workspace = true }
nym-service-provider-requests-common = { workspace = true }
nym-sphinx = { workspace = true }
nym-wireguard-types = { workspace = true }
nym-credentials-interface = { path = "../credentials-interface" }
nym-crypto = { path = "../crypto", features = ["asymmetric"] }
nym-network-defaults = { path = "../network-defaults" }
nym-service-provider-requests-common = { path = "../service-provider-requests-common" }
nym-sphinx = { path = "../nymsphinx" }
nym-wireguard-types = { path = "../wireguard-types" }
## verify:
hmac = { workspace = true, optional = true }
@@ -32,7 +31,7 @@ sha2 = { workspace = true, optional = true }
x25519-dalek = { workspace = true, features = ["static_secrets"] }
[dev-dependencies]
nym-test-utils = { workspace = true }
nym-test-utils = { path = "../test-utils" }
[features]
default = ["verify"]
@@ -40,4 +39,4 @@ default = ["verify"]
verify = ["hmac", "sha2"]
[lints]
workspace = true
workspace = true
+9 -13
View File
@@ -1,12 +1,8 @@
[package]
name = "nym-bandwidth-controller"
version.workspace = true
version = "0.1.0"
edition = "2021"
license.workspace = true
description = "Crate for controlling the use of zknym credentials to ensure constant bandwidth availability for NymVPN app"
repository.workspace = true
homepage.workspace = true
documentation.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -16,14 +12,14 @@ log = { workspace = true }
rand = { workspace = true }
thiserror = { workspace = true }
nym-credential-storage = { workspace = true }
nym-credentials = { workspace = true }
nym-credentials-interface = { workspace = true }
nym-crypto = { workspace = true, features = ["rand", "asymmetric", "stream_cipher", "aes", "hashing"] }
nym-ecash-time = { workspace = true }
nym-task = { workspace = true }
nym-validator-client = { workspace = true }
nym-credential-storage = { path = "../credential-storage" }
nym-credentials = { path = "../credentials" }
nym-credentials-interface = { path = "../credentials-interface" }
nym-crypto = { path = "../crypto", features = ["rand", "asymmetric", "stream_cipher", "aes", "hashing"] }
nym-ecash-time = { path = "../ecash-time" }
nym-task = { path = "../task" }
nym-validator-client = { path = "../client-libs/validator-client", default-features = false }
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.nym-validator-client]
workspace = true
path = "../client-libs/validator-client"
features = ["http-client"]
-1
View File
@@ -28,7 +28,6 @@ pub use traits::{BandwidthTicketProvider, DEFAULT_TICKETS_TO_SPEND};
pub mod acquire;
pub mod error;
mod event;
pub mod mock;
mod traits;
mod utils;
-120
View File
@@ -1,120 +0,0 @@
// Copyright 2026 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
#![allow(clippy::expect_used)]
use crate::error::BandwidthControllerError;
use crate::{BandwidthTicketProvider, PreparedCredential, PreparedCredentialMetadata};
use async_trait::async_trait;
use nym_credentials_interface::{CredentialSpendingData, TicketType};
use nym_crypto::asymmetric::ed25519::PublicKey;
use nym_ecash_time::OffsetDateTime;
#[derive(Default)]
pub struct MockBandwidthController {
// TODO: inject proper bls381 keys and just sign credentials
//
}
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl BandwidthTicketProvider for MockBandwidthController {
async fn get_ecash_ticket(
&self,
_ticket_type: TicketType,
_gateway_id: PublicKey,
tickets_to_spend: u32,
) -> Result<PreparedCredential, BandwidthControllerError> {
assert_eq!(tickets_to_spend, 1);
// This is a valid serialized CredentialSpendingData taken from integration tests
// See: common/wireguard-private-metadata/tests/src/lib.rs:CREDENTIAL_BYTES
const CREDENTIAL_BYTES: [u8; 1245] = [
0, 0, 4, 133, 96, 179, 223, 185, 136, 23, 213, 166, 59, 203, 66, 69, 209, 181, 227,
254, 16, 102, 98, 237, 59, 119, 170, 111, 31, 194, 51, 59, 120, 17, 115, 229, 79, 91,
11, 139, 154, 2, 212, 23, 68, 70, 167, 3, 240, 54, 224, 171, 221, 1, 69, 48, 60, 118,
119, 249, 123, 35, 172, 227, 131, 96, 232, 209, 187, 123, 4, 197, 102, 90, 96, 45, 125,
135, 140, 99, 1, 151, 17, 131, 143, 157, 97, 107, 139, 232, 212, 87, 14, 115, 253, 255,
166, 167, 186, 43, 90, 96, 173, 105, 120, 40, 10, 163, 250, 224, 214, 200, 178, 4, 160,
16, 130, 59, 76, 193, 39, 240, 3, 101, 141, 209, 183, 226, 186, 207, 56, 210, 187, 7,
164, 240, 164, 205, 37, 81, 184, 214, 193, 195, 90, 205, 238, 225, 195, 104, 12, 123,
203, 57, 233, 243, 215, 145, 195, 196, 57, 38, 125, 172, 18, 47, 63, 165, 110, 219,
180, 40, 58, 116, 92, 254, 160, 98, 48, 92, 254, 232, 107, 184, 80, 234, 60, 160, 235,
249, 76, 41, 38, 165, 28, 40, 136, 74, 48, 166, 50, 245, 23, 201, 140, 101, 79, 93,
235, 128, 186, 146, 126, 180, 134, 43, 13, 186, 19, 195, 48, 168, 201, 29, 216, 95,
176, 198, 132, 188, 64, 39, 212, 150, 32, 52, 53, 38, 228, 199, 122, 226, 217, 75, 40,
191, 151, 48, 164, 242, 177, 79, 14, 122, 105, 151, 85, 88, 199, 162, 17, 96, 103, 83,
178, 128, 9, 24, 30, 74, 108, 241, 85, 240, 166, 97, 241, 85, 199, 11, 198, 226, 234,
70, 107, 145, 28, 208, 114, 51, 12, 234, 108, 101, 202, 112, 48, 185, 22, 159, 67, 109,
49, 27, 149, 90, 109, 32, 226, 112, 7, 201, 208, 209, 104, 31, 97, 134, 204, 145, 27,
181, 206, 181, 106, 32, 110, 136, 115, 249, 201, 111, 5, 245, 203, 71, 121, 169, 126,
151, 178, 236, 59, 221, 195, 48, 135, 115, 6, 50, 227, 74, 97, 107, 107, 213, 90, 2,
203, 154, 138, 47, 128, 52, 134, 128, 224, 51, 65, 240, 90, 8, 55, 175, 180, 178, 204,
206, 168, 110, 51, 57, 189, 169, 48, 169, 136, 121, 99, 51, 170, 178, 214, 74, 1, 96,
151, 167, 25, 173, 180, 171, 155, 10, 55, 142, 234, 190, 113, 90, 79, 80, 244, 71, 166,
30, 235, 113, 150, 133, 1, 218, 17, 109, 111, 223, 24, 216, 177, 41, 2, 204, 65, 221,
212, 207, 236, 144, 6, 65, 224, 55, 42, 1, 1, 161, 134, 118, 127, 111, 220, 110, 127,
240, 71, 223, 129, 12, 93, 20, 220, 60, 56, 71, 146, 184, 95, 132, 69, 28, 56, 53, 192,
213, 22, 119, 230, 152, 225, 182, 188, 163, 219, 37, 175, 247, 73, 14, 247, 38, 72,
243, 1, 48, 131, 59, 8, 13, 96, 143, 185, 127, 241, 161, 217, 24, 149, 193, 40, 16, 30,
202, 151, 28, 119, 240, 153, 101, 156, 61, 193, 72, 245, 199, 181, 12, 231, 65, 166,
67, 142, 121, 207, 202, 58, 197, 113, 188, 248, 42, 124, 105, 48, 161, 241, 55, 209,
36, 194, 27, 63, 233, 144, 189, 85, 117, 234, 9, 139, 46, 31, 206, 114, 95, 131, 29,
240, 13, 81, 142, 140, 133, 33, 30, 41, 141, 37, 80, 217, 95, 221, 76, 115, 86, 201,
165, 51, 252, 9, 28, 209, 1, 48, 150, 74, 248, 212, 187, 222, 66, 210, 3, 200, 19, 217,
171, 184, 42, 148, 53, 150, 57, 50, 6, 227, 227, 62, 49, 42, 148, 148, 157, 82, 191,
58, 24, 34, 56, 98, 120, 89, 105, 176, 85, 15, 253, 241, 41, 153, 195, 136, 1, 48, 142,
126, 213, 101, 223, 79, 133, 230, 105, 38, 161, 149, 2, 21, 136, 150, 42, 72, 218, 85,
146, 63, 223, 58, 108, 186, 183, 248, 62, 20, 47, 34, 113, 160, 177, 204, 181, 16, 24,
212, 224, 35, 84, 51, 168, 56, 136, 11, 1, 48, 135, 242, 62, 149, 230, 178, 32, 224,
119, 26, 234, 163, 237, 224, 114, 95, 112, 140, 170, 150, 96, 125, 136, 221, 180, 78,
18, 11, 12, 184, 2, 198, 217, 119, 43, 69, 4, 172, 109, 55, 183, 40, 131, 172, 161, 88,
183, 101, 1, 48, 173, 216, 22, 73, 42, 255, 211, 93, 249, 87, 159, 115, 61, 91, 55,
130, 17, 216, 60, 34, 122, 55, 8, 244, 244, 153, 151, 57, 5, 144, 178, 55, 249, 64,
211, 168, 34, 148, 56, 89, 92, 203, 70, 124, 219, 152, 253, 165, 0, 32, 203, 116, 63,
7, 240, 222, 82, 86, 11, 149, 167, 72, 224, 55, 190, 66, 201, 65, 168, 184, 96, 47,
194, 241, 168, 124, 7, 74, 214, 250, 37, 76, 32, 218, 69, 122, 103, 215, 145, 169, 24,
212, 229, 168, 106, 10, 144, 31, 13, 25, 178, 242, 250, 106, 159, 40, 48, 163, 165, 61,
130, 57, 146, 4, 73, 32, 254, 233, 125, 135, 212, 29, 111, 4, 177, 114, 15, 210, 170,
82, 108, 110, 62, 166, 81, 209, 106, 176, 156, 14, 133, 242, 60, 127, 120, 242, 28, 97,
0, 1, 32, 103, 93, 109, 89, 240, 91, 1, 84, 150, 50, 206, 157, 203, 49, 220, 120, 234,
175, 234, 150, 126, 225, 94, 163, 164, 199, 138, 114, 62, 99, 106, 112, 1, 32, 171, 40,
220, 82, 241, 203, 76, 146, 111, 139, 182, 179, 237, 182, 115, 75, 128, 201, 107, 43,
214, 0, 135, 217, 160, 68, 150, 232, 144, 114, 237, 98, 32, 30, 134, 232, 59, 93, 163,
253, 244, 13, 202, 52, 147, 168, 83, 121, 123, 95, 21, 210, 209, 225, 223, 143, 49, 10,
205, 238, 1, 22, 83, 81, 70, 1, 32, 26, 76, 6, 234, 160, 50, 139, 102, 161, 232, 155,
106, 130, 171, 226, 210, 233, 178, 85, 247, 71, 123, 55, 53, 46, 67, 148, 137, 156,
207, 208, 107, 1, 32, 102, 31, 4, 98, 110, 156, 144, 61, 229, 140, 198, 84, 196, 238,
128, 35, 131, 182, 137, 125, 241, 95, 69, 131, 170, 27, 2, 144, 75, 72, 242, 102, 3,
32, 121, 80, 45, 173, 56, 65, 218, 27, 40, 251, 197, 32, 169, 104, 123, 110, 90, 78,
153, 166, 38, 9, 129, 228, 99, 8, 1, 116, 142, 233, 162, 69, 32, 216, 169, 159, 116,
95, 12, 63, 176, 195, 6, 183, 123, 135, 75, 61, 112, 106, 83, 235, 176, 41, 27, 248,
48, 71, 165, 170, 12, 92, 103, 103, 81, 32, 58, 74, 75, 145, 192, 94, 153, 69, 80, 128,
241, 3, 16, 117, 192, 86, 161, 103, 44, 174, 211, 196, 182, 124, 55, 11, 107, 142, 49,
88, 6, 41, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0, 37, 139, 240, 0, 0, 0, 0, 0,
0, 0, 1,
];
let mut credential = CredentialSpendingData::try_from_bytes(&CREDENTIAL_BYTES)
.expect("Failed to deserialize test credential - this is a bug in the test harness");
// Update spend_date to today to pass validation
credential.spend_date = OffsetDateTime::now_utc().date();
Ok(PreparedCredential {
data: credential,
epoch_id: 0,
metadata: PreparedCredentialMetadata {
ticketbook_id: 0,
tickets_withdrawn: 1,
used_tickets: 0,
},
})
}
async fn get_upgrade_mode_token(&self) -> Result<Option<String>, BandwidthControllerError> {
Ok(None)
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "nym-bin-common"
version.workspace = true
version = "0.6.0"
description = "Common code for nym binaries"
edition = { workspace = true }
authors = { workspace = true }
@@ -124,10 +124,6 @@ impl BinaryBuildInformation {
}
}
// to whoever is thinking of modifying this struct.
// you MUST NOT change its structure in any way - adding, removing or changing fields
// otherwise, it will break old clients as bincode serialisation is not backwards compatible
// even if you put `#[serde(default)]` all over the place
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
#[cfg_attr(feature = "bin_info_schema", derive(schemars::JsonSchema))]
+25 -29
View File
@@ -1,14 +1,10 @@
[package]
name = "nym-client-core"
version.workspace = true
version = "1.1.15"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
edition = "2021"
rust-version = "1.85"
license.workspace = true
description = "Crate containing core client functionality and configs, used by all other Nym client implentations"
repository.workspace = true
homepage.workspace = true
documentation.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -35,32 +31,32 @@ tracing = { workspace = true }
zeroize = { workspace = true }
# internal
nym-id = { workspace = true }
nym-bandwidth-controller = { workspace = true }
nym-crypto = { workspace = true }
nym-gateway-client = { workspace = true }
nym-gateway-requests = { workspace = true }
nym-http-api-client = { workspace = true, features = ["network-defaults"] }
nym-nonexhaustive-delayqueue = { workspace = true }
nym-sphinx = { workspace = true }
nym-statistics-common = { workspace = true }
nym-pemstore = { workspace = true }
nym-topology = { workspace = true, features = ["persistence"] }
nym-validator-client = { workspace = true }
nym-task = { workspace = true }
nym-credentials-interface = { workspace = true }
nym-credential-storage = { workspace = true }
nym-network-defaults = { workspace = true }
nym-client-core-config-types = { workspace = true, features = [
nym-id = { path = "../nym-id" }
nym-bandwidth-controller = { path = "../bandwidth-controller" }
nym-crypto = { path = "../crypto" }
nym-gateway-client = { path = "../client-libs/gateway-client" }
nym-gateway-requests = { path = "../gateway-requests" }
nym-http-api-client = { path = "../http-api-client", features = ["network-defaults"] }
nym-nonexhaustive-delayqueue = { path = "../nonexhaustive-delayqueue" }
nym-sphinx = { path = "../nymsphinx" }
nym-statistics-common = { path = "../statistics" }
nym-pemstore = { path = "../pemstore" }
nym-topology = { path = "../topology", features = ["persistence"] }
nym-validator-client = { path = "../client-libs/validator-client", default-features = false }
nym-task = { path = "../task" }
nym-credentials-interface = { path = "../credentials-interface" }
nym-credential-storage = { path = "../credential-storage" }
nym-network-defaults = { path = "../network-defaults" }
nym-client-core-config-types = { path = "./config-types", features = [
"disk-persistence",
] }
nym-client-core-surb-storage = { workspace = true }
nym-client-core-gateways-storage = { workspace = true }
nym-ecash-time = { workspace = true }
nym-mixnet-contract-common = { workspace = true }
nym-client-core-surb-storage = { path = "./surb-storage" }
nym-client-core-gateways-storage = { path = "./gateways-storage" }
nym-ecash-time = { path = "../ecash-time" }
nym-mixnet-contract-common = { path = "../cosmwasm-smart-contracts/mixnet-contract" }
[target."cfg(not(target_arch = \"wasm32\"))".dependencies]
nym-mixnet-client = { workspace = true }
nym-mixnet-client = { path = "../client-libs/mixnet-client", default-features = false }
### For serving prometheus metrics
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.hyper]
@@ -109,8 +105,8 @@ features = ["tokio"]
workspace = true
features = ["futures"]
[target."cfg(target_arch = \"wasm32\")".dependencies.nym-wasm-utils]
workspace = true
[target."cfg(target_arch = \"wasm32\")".dependencies.wasm-utils]
path = "../wasm/utils"
features = ["websocket"]
[target."cfg(target_arch = \"wasm32\")".dependencies.time]
+6 -10
View File
@@ -1,12 +1,8 @@
[package]
name = "nym-client-core-config-types"
version.workspace = true
version = "0.1.0"
edition = "2021"
license.workspace = true
description = "Low level configs and constants used by Nym clients and nodes"
repository.workspace = true
homepage.workspace = true
documentation.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -16,14 +12,14 @@ serde = { workspace = true, features = ["derive"] }
thiserror.workspace = true
url = { workspace = true, features = ["serde"] }
nym-config = { workspace = true }
nym-config = { path = "../../config" }
nym-pemstore = { workspace = true , optional = true }
nym-pemstore = { path = "../../pemstore", optional = true }
# those are pulling so many deps T.T
nym-sphinx-params = { workspace = true }
nym-sphinx-addressing = { workspace = true }
nym-statistics-common = { workspace = true }
nym-sphinx-params = { path = "../../nymsphinx/params" }
nym-sphinx-addressing = { path = "../../nymsphinx/addressing" }
nym-statistics-common = { path = "../../statistics" }
[features]
@@ -1,13 +1,9 @@
[package]
name = "nym-client-core-gateways-storage"
version.workspace = true
version = "0.1.0"
edition = "2021"
license.workspace = true
rust-version.workspace = true
description = "Functionality for Nym clients to store and retrive Gateway connections"
repository.workspace = true
homepage.workspace = true
documentation.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -21,9 +17,9 @@ tracing.workspace = true
url.workspace = true
zeroize = { workspace = true, features = ["zeroize_derive"] }
nym-crypto = { workspace = true, features = ["asymmetric"] }
nym-gateway-requests = { workspace = true}
nym-gateway-client = { workspace = true}
nym-crypto = { path = "../../crypto", features = ["asymmetric"] }
nym-gateway-requests = { path = "../../gateway-requests" }
nym-gateway-client = { path = "../../client-libs/gateway-client" }
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.sqlx]
workspace = true
@@ -71,7 +71,7 @@ use url::Url;
#[cfg(target_arch = "wasm32")]
#[cfg(debug_assertions)]
use nym_wasm_utils::console_log;
use wasm_utils::console_log;
/// Default number of retries for Nym API requests when using network details with domain fronting.
/// This allows the client to try alternative URLs if the primary endpoint is unavailable.
@@ -31,7 +31,7 @@ use tracing::*;
#[cfg(not(target_arch = "wasm32"))]
use tokio::time::{sleep, Sleep};
// use nym_wasm_utils::console_log;
// use wasm_utils::console_log;
#[cfg(target_arch = "wasm32")]
use wasmtimer::tokio::{sleep, Sleep};
mod sending_delay_controller;
+2 -2
View File
@@ -23,8 +23,6 @@ use url::Url;
use crate::init::websockets::connect_async;
use nym_topology::NodeId;
#[cfg(target_arch = "wasm32")]
use nym_wasm_utils::websocket::JSWebsocket;
#[cfg(not(target_arch = "wasm32"))]
use tokio::net::TcpStream;
#[cfg(not(target_arch = "wasm32"))]
@@ -34,6 +32,8 @@ use tokio::time::Instant;
#[cfg(not(target_arch = "wasm32"))]
use tokio_tungstenite::{MaybeTlsStream, WebSocketStream};
#[cfg(target_arch = "wasm32")]
use wasm_utils::websocket::JSWebsocket;
#[cfg(target_arch = "wasm32")]
use wasmtimer::std::Instant;
#[cfg(target_arch = "wasm32")]
use wasmtimer::tokio::sleep;
+6 -10
View File
@@ -1,12 +1,8 @@
[package]
name = "nym-client-core-surb-storage"
version.workspace = true
version = "0.1.0"
edition = "2021"
license.workspace = true
description = "Functionality for Nym clients to generate and use Single Use Reply Blocks (SURBs)"
repository.workspace = true
homepage.workspace = true
documentation.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -17,9 +13,9 @@ tracing.workspace = true
thiserror.workspace = true
time.workspace = true
nym-crypto = { workspace = true, optional = true, default-features = false }
nym-sphinx = { workspace = true }
nym-task = { workspace = true }
nym-crypto = { path = "../../crypto", optional = true, default-features = false }
nym-sphinx = { path = "../../nymsphinx" }
nym-task = { path = "../../task" }
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio]
workspace = true
@@ -30,8 +26,8 @@ workspace = true
features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate", "time"]
optional = true
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.nym-sqlx-pool-guard]
workspace = true
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.sqlx-pool-guard]
path = "../../../sqlx-pool-guard"
[build-dependencies]
anyhow = { workspace = true }
@@ -13,7 +13,7 @@ use std::path::Path;
use time::OffsetDateTime;
use tracing::{error, info};
use nym_sqlx_pool_guard::SqlitePoolGuard;
use sqlx_pool_guard::SqlitePoolGuard;
#[derive(Debug, Clone)]
pub struct StorageManager {
+17 -21
View File
@@ -1,13 +1,9 @@
[package]
name = "nym-gateway-client"
version.workspace = true
version = "0.1.0"
authors = ["Jędrzej Stuczyński <andrew@nymtech.net>"]
edition = "2021"
license.workspace = true
description = "Functions and types for Nym client <> Gateway connections"
repository.workspace = true
homepage.workspace = true
documentation.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -25,19 +21,19 @@ time.workspace = true
zeroize.workspace = true
# internal
nym-bandwidth-controller = { workspace = true }
nym-credentials = { workspace = true }
nym-credential-storage = { workspace = true }
nym-credentials-interface = { workspace = true }
nym-crypto = { workspace = true }
nym-gateway-requests = { workspace = true }
nym-http-api-client = { workspace = true }
nym-network-defaults = { workspace = true }
nym-sphinx = { workspace = true }
nym-statistics-common = { workspace = true }
nym-pemstore = { workspace = true }
nym-validator-client = { workspace = true, default-features = false }
nym-task = { workspace = true }
nym-bandwidth-controller = { path = "../../bandwidth-controller" }
nym-credentials = { path = "../../credentials" }
nym-credential-storage = { path = "../../credential-storage" }
nym-credentials-interface = { path = "../../credentials-interface" }
nym-crypto = { path = "../../crypto" }
nym-gateway-requests = { path = "../../gateway-requests" }
nym-http-api-client = { path = "../../http-api-client" }
nym-network-defaults = { path = "../../network-defaults" }
nym-sphinx = { path = "../../nymsphinx" }
nym-statistics-common = { path = "../../statistics" }
nym-pemstore = { path = "../../pemstore" }
nym-validator-client = { path = "../validator-client", default-features = false }
nym-task = { path = "../../task" }
serde = { workspace = true, features = ["derive"] }
@@ -65,8 +61,8 @@ workspace = true
[target."cfg(target_arch = \"wasm32\")".dependencies.wasm-bindgen-futures]
workspace = true
[target."cfg(target_arch = \"wasm32\")".dependencies.nym-wasm-utils]
workspace = true
[target."cfg(target_arch = \"wasm32\")".dependencies.wasm-utils]
path = "../../wasm/utils"
features = ["websocket"]
[target."cfg(target_arch = \"wasm32\")".dependencies.gloo-utils]
@@ -94,4 +90,4 @@ features = ["js"]
wasm = []
[lints]
workspace = true
workspace = true
@@ -41,11 +41,11 @@ use std::os::fd::RawFd;
#[cfg(not(target_arch = "wasm32"))]
use tokio::time::sleep;
#[cfg(target_arch = "wasm32")]
use nym_wasm_utils::websocket::JSWebsocket;
#[cfg(not(unix))]
use std::os::raw::c_int as RawFd;
#[cfg(target_arch = "wasm32")]
use wasm_utils::websocket::JSWebsocket;
#[cfg(target_arch = "wasm32")]
use wasmtimer::tokio::sleep;
pub mod config;
@@ -29,7 +29,7 @@ use tokio::net::TcpStream;
use tokio_tungstenite::{MaybeTlsStream, WebSocketStream};
#[cfg(target_arch = "wasm32")]
use nym_wasm_utils::websocket::JSWebsocket;
use wasm_utils::websocket::JSWebsocket;
// type alias for not having to type the whole thing every single time (and now it makes it easier
// to use different types based on compilation target)
+5 -9
View File
@@ -1,13 +1,9 @@
[package]
name = "nym-mixnet-client"
version.workspace = true
version = "0.1.0"
authors = ["Jedrzej Stuczynski <andrew@nymtech.net>"]
edition = "2021"
license.workspace = true
description = "Client for Mix Node <> Mix Node & Mix Node <> Gateway communication"
repository.workspace = true
homepage.workspace = true
documentation.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -20,14 +16,14 @@ tokio-util = { workspace = true, features = ["codec"], optional = true }
tokio-stream = { workspace = true }
# internal
nym-noise = { workspace = true }
nym-sphinx = { workspace = true }
nym-task = { workspace = true, optional = true }
nym-noise = { path = "../../nymnoise" }
nym-sphinx = { path = "../../nymsphinx" }
nym-task = { path = "../../task", optional = true }
[features]
default = ["client"]
client = ["tokio-util", "nym-task", "tokio/net", "tokio/rt"]
[dev-dependencies]
nym-crypto = { workspace = true }
nym-crypto = { path = "../../crypto" }
rand = { workspace = true }
+15 -19
View File
@@ -1,14 +1,10 @@
[package]
name = "nym-validator-client"
version.workspace = true
version = "0.1.0"
authors = ["Jędrzej Stuczyński <andrew@nymtech.net>"]
edition = "2021"
rust-version = "1.85"
license.workspace = true
description = "Client for interacting with Nyx Cosmos SDK blockchain"
repository.workspace = true
homepage.workspace = true
documentation.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -16,18 +12,18 @@ documentation.workspace = true
base64 = { workspace = true }
colored = { workspace = true }
nym-coconut-dkg-common = { workspace = true }
nym-contracts-common = { workspace = true }
nym-mixnet-contract-common = { workspace = true }
nym-vesting-contract-common = { workspace = true }
nym-ecash-contract-common = { workspace = true }
nym-multisig-contract-common = { workspace = true }
nym-group-contract-common = { workspace = true }
nym-performance-contract-common = { workspace = true }
nym-serde-helpers = { workspace = true, features = ["hex", "base64"] }
nym-coconut-dkg-common = { path = "../../cosmwasm-smart-contracts/coconut-dkg" }
nym-contracts-common = { path = "../../cosmwasm-smart-contracts/contracts-common" }
nym-mixnet-contract-common = { path = "../../cosmwasm-smart-contracts/mixnet-contract" }
nym-vesting-contract-common = { path = "../../cosmwasm-smart-contracts/vesting-contract" }
nym-ecash-contract-common = { path = "../../cosmwasm-smart-contracts/ecash-contract" }
nym-multisig-contract-common = { path = "../../cosmwasm-smart-contracts/multisig-contract" }
nym-group-contract-common = { path = "../../cosmwasm-smart-contracts/group-contract" }
nym-performance-contract-common = { path = "../../cosmwasm-smart-contracts/nym-performance-contract" }
nym-serde-helpers = { path = "../../serde-helpers", features = ["hex", "base64"] }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
nym-http-api-client = { workspace = true }
nym-http-api-client = { path = "../../../common/http-api-client" }
thiserror = { workspace = true }
tracing = { workspace = true }
url = { workspace = true, features = ["serde"] }
@@ -35,13 +31,13 @@ tokio = { workspace = true, features = ["sync", "time"] }
time = { workspace = true, features = ["formatting"] }
futures = { workspace = true }
nym-compact-ecash = { workspace = true }
nym-network-defaults = { workspace = true }
nym-api-requests = { workspace = true }
nym-compact-ecash = { path = "../../nym_offline_compact_ecash" }
nym-network-defaults = { path = "../../network-defaults" }
nym-api-requests = { path = "../../../nym-api/nym-api-requests" }
async-trait = { workspace = true }
bip39 = { workspace = true, features = ["rand"] }
nym-config = { workspace = true }
nym-config = { path = "../../config" }
cosmrs = { workspace = true, features = ["bip32", "cosmwasm"] }
# note that this has the same version as used by cosmrs
@@ -20,7 +20,7 @@ use nym_api_requests::ecash::{
};
use nym_api_requests::models::{
ApiHealthResponse, GatewayCoreStatusResponse, HistoricalPerformanceResponse,
MixnodeCoreStatusResponse, NymNodeDescriptionV1, NymNodeDescriptionV2,
MixnodeCoreStatusResponse, NymNodeDescription,
};
use nym_api_requests::nym_nodes::{
NodesByAddressesResponse, SemiSkimmedNodesWithMetadata, SkimmedNode, SkimmedNodesWithMetadata,
@@ -273,23 +273,48 @@ impl<C, S> Client<C, S> {
Ok(history)
}
#[deprecated(note = "use get_all_cached_described_nodes_v2 instead")]
// TODO: combine with NymApiClient...
pub async fn get_all_cached_described_nodes(
&self,
) -> Result<Vec<NymNodeDescriptionV1>, ValidatorClientError> {
Ok(self.nym_api.get_all_described_nodes().await?)
}
pub async fn get_all_cached_described_nodes_v2(
&self,
) -> Result<Vec<NymNodeDescriptionV2>, ValidatorClientError> {
Ok(self.nym_api.get_all_described_nodes_v2().await?)
) -> Result<Vec<NymNodeDescription>, ValidatorClientError> {
// TODO: deal with paging in macro or some helper function or something, because it's the same pattern everywhere
let mut page = 0;
let mut descriptions = Vec::new();
loop {
let mut res = self.nym_api.get_nodes_described(Some(page), None).await?;
descriptions.append(&mut res.data);
if descriptions.len() < res.pagination.total {
page += 1
} else {
break;
}
}
Ok(descriptions)
}
// TODO: combine with NymApiClient...
pub async fn get_all_cached_bonded_nym_nodes(
&self,
) -> Result<Vec<NymNodeDetails>, ValidatorClientError> {
self.nym_api.get_all_bonded_nym_nodes().await
// TODO: deal with paging in macro or some helper function or something, because it's the same pattern everywhere
let mut page = 0;
let mut bonds = Vec::new();
loop {
let mut res = self.nym_api.get_nym_nodes(Some(page), None).await?;
bonds.append(&mut res.data);
if bonds.len() < res.pagination.total {
page += 1
} else {
break;
}
}
Ok(bonds)
}
pub async fn blind_sign(
@@ -473,10 +498,9 @@ impl NymApiClient {
Ok(self.nym_api.health().await?)
}
#[deprecated(note = "use .get_all_described_nodes_v2 instead")]
pub async fn get_all_described_nodes(
&self,
) -> Result<Vec<NymNodeDescriptionV1>, ValidatorClientError> {
) -> Result<Vec<NymNodeDescription>, ValidatorClientError> {
// TODO: deal with paging in macro or some helper function or something, because it's the same pattern everywhere
let mut page = 0;
let mut descriptions = Vec::new();
@@ -495,30 +519,6 @@ impl NymApiClient {
Ok(descriptions)
}
pub async fn get_all_described_nodes_v2(
&self,
) -> Result<Vec<NymNodeDescriptionV2>, ValidatorClientError> {
// TODO: deal with paging in macro or some helper function or something, because it's the same pattern everywhere
let mut page = 0;
let mut descriptions = Vec::new();
loop {
let mut res = self
.nym_api
.get_nodes_described_v2(Some(page), None)
.await?;
descriptions.append(&mut res.data);
if descriptions.len() < res.pagination.total {
page += 1
} else {
break;
}
}
Ok(descriptions)
}
pub async fn get_all_bonded_nym_nodes(
&self,
) -> Result<Vec<NymNodeDetails>, ValidatorClientError> {
@@ -17,8 +17,7 @@ use nym_api_requests::ecash::VerificationKeyResponse;
use nym_api_requests::models::{
AnnotationResponse, ApiHealthResponse, BinaryBuildInformationOwned, ChainBlocksStatusResponse,
ChainStatusResponse, KeyRotationInfoResponse, NodePerformanceResponse, NodeRefreshBody,
NymNodeDescriptionV1, NymNodeDescriptionV2, PerformanceHistoryResponse, RewardedSetResponse,
SignerInformationResponse,
NymNodeDescription, PerformanceHistoryResponse, RewardedSetResponse, SignerInformationResponse,
};
use nym_api_requests::nym_nodes::{
NodesByAddressesRequestBody, NodesByAddressesResponse, PaginatedCachedNodesResponseV1,
@@ -117,12 +116,11 @@ pub trait NymApiClientExt: ApiClient {
}
#[tracing::instrument(level = "debug", skip_all)]
#[deprecated(note = "use .get_nodes_described_v2 instead")]
async fn get_nodes_described(
&self,
page: Option<u32>,
per_page: Option<u32>,
) -> Result<PaginatedResponse<NymNodeDescriptionV1>, NymAPIError> {
) -> Result<PaginatedResponse<NymNodeDescription>, NymAPIError> {
let mut params = Vec::new();
if let Some(page) = page {
@@ -144,33 +142,6 @@ pub trait NymApiClientExt: ApiClient {
.await
}
#[tracing::instrument(level = "debug", skip_all)]
async fn get_nodes_described_v2(
&self,
page: Option<u32>,
per_page: Option<u32>,
) -> Result<PaginatedResponse<NymNodeDescriptionV2>, NymAPIError> {
let mut params = Vec::new();
if let Some(page) = page {
params.push(("page", page.to_string()))
}
if let Some(per_page) = per_page {
params.push(("per_page", per_page.to_string()))
}
self.get_json(
&[
routes::V2_API_VERSION,
routes::NYM_NODES_ROUTES,
routes::NYM_NODES_DESCRIBED,
],
&params,
)
.await
}
async fn get_current_rewarded_set(&self) -> Result<RewardedSetResponse, NymAPIError> {
self.get_rewarded_set().await
}
@@ -302,9 +273,7 @@ pub trait NymApiClientExt: ApiClient {
Ok(SkimmedNodesWithMetadata::new(nodes, metadata))
}
#[deprecated(note = "use .get_all_described_nodes_v2 instead")]
#[allow(deprecated)]
async fn get_all_described_nodes(&self) -> Result<Vec<NymNodeDescriptionV1>, NymAPIError> {
async fn get_all_described_nodes(&self) -> Result<Vec<NymNodeDescription>, NymAPIError> {
// TODO: deal with paging in macro or some helper function or something, because it's the same pattern everywhere
let mut page = 0;
let mut descriptions = Vec::new();
@@ -323,25 +292,6 @@ pub trait NymApiClientExt: ApiClient {
Ok(descriptions)
}
async fn get_all_described_nodes_v2(&self) -> Result<Vec<NymNodeDescriptionV2>, NymAPIError> {
// TODO: deal with paging in macro or some helper function or something, because it's the same pattern everywhere
let mut page = 0;
let mut descriptions = Vec::new();
loop {
let mut res = self.get_nodes_described_v2(Some(page), None).await?;
descriptions.append(&mut res.data);
if descriptions.len() < res.pagination.total {
page += 1
} else {
break;
}
}
Ok(descriptions)
}
#[tracing::instrument(level = "debug", skip_all)]
async fn get_nym_nodes(
&self,
+25 -29
View File
@@ -1,13 +1,9 @@
[package]
name = "nym-cli-commands"
version.workspace = true
version = "1.0.0"
authors.workspace = true
edition = "2021"
license.workspace = true
description = "Common commands crate used by the nym-cli tool for interacting with the Nyx Cosmos SDK blockchain and Mixnet endpoints"
repository.workspace = true
homepage.workspace = true
documentation.workspace = true
[dependencies]
anyhow = { workspace = true }
@@ -41,28 +37,28 @@ zeroize = { workspace = true }
cosmrs = { workspace = true }
cosmwasm-std = { workspace = true }
nym-validator-client = { workspace = true}
nym-http-api-client = { workspace = true}
nym-bin-common = { workspace = true, features = ["output_format"] }
nym-crypto = { workspace = true, features = ["asymmetric"] }
nym-network-defaults = { workspace = true }
nym-contracts-common = { workspace = true }
nym-bandwidth-controller = { workspace = true }
nym-mixnet-contract-common = { workspace = true }
nym-vesting-contract-common = { workspace = true }
nym-coconut-dkg-common = { workspace = true }
nym-multisig-contract-common = { workspace = true }
nym-ecash-contract-common = { workspace = true }
nym-ecash-time = { workspace = true }
nym-sphinx = { workspace = true }
nym-client-core = { workspace = true }
nym-config = { workspace = true }
nym-credentials = { workspace = true }
nym-credentials-interface = { workspace = true }
nym-credential-storage = { workspace = true }
nym-credential-utils = { workspace = true }
nym-id = { workspace = true }
nym-credential-proxy-requests = { workspace = true }
nym-validator-client = { path = "../client-libs/validator-client" }
nym-http-api-client = { path = "../http-api-client" }
nym-bin-common = { path = "../../common/bin-common", features = ["output_format"] }
nym-crypto = { path = "../../common/crypto", features = ["asymmetric"] }
nym-network-defaults = { path = "../network-defaults" }
nym-contracts-common = { path = "../cosmwasm-smart-contracts/contracts-common" }
nym-bandwidth-controller = { path = "../../common/bandwidth-controller" }
nym-mixnet-contract-common = { path = "../cosmwasm-smart-contracts/mixnet-contract" }
nym-vesting-contract-common = { path = "../cosmwasm-smart-contracts/vesting-contract" }
nym-coconut-dkg-common = { path = "../cosmwasm-smart-contracts/coconut-dkg" }
nym-multisig-contract-common = { path = "../cosmwasm-smart-contracts/multisig-contract" }
nym-ecash-contract-common = { path = "../cosmwasm-smart-contracts/ecash-contract" }
nym-ecash-time = { path = "../../common/ecash-time" }
nym-sphinx = { path = "../../common/nymsphinx" }
nym-client-core = { path = "../../common/client-core" }
nym-config = { path = "../../common/config" }
nym-credentials = { path = "../../common/credentials" }
nym-credentials-interface = { path = "../../common/credentials-interface" }
nym-credential-storage = { path = "../../common/credential-storage" }
nym-credential-utils = { path = "../../common/credential-utils" }
nym-id = { path = "../nym-id" }
nym-credential-proxy-requests = { path = "../../nym-credential-proxy/nym-credential-proxy-requests" }
nym-pemstore = { workspace = true }
nym-types = { workspace = true }
nym-pemstore = { path = "../../common/pemstore", version = "0.3.0" }
nym-types = { path = "../../common/types" }
+1 -1
View File
@@ -105,7 +105,7 @@ pub(crate) enum CommonConfigsWrapper {
// nym-api
NymApi(NymApiConfigLight),
// anything else that might get introduced
// anything else that might get get introduced
Unknown(UnknownConfigWrapper),
}
@@ -14,7 +14,7 @@ pub struct Args {
}
pub async fn query(args: Args, client: &QueryClientWithNyxd) {
match client.get_all_cached_described_nodes_v2().await {
match client.get_all_cached_described_nodes().await {
Ok(res) => match args.identity_key {
Some(identity_key) => {
let node = res.iter().find(|node| {
@@ -14,7 +14,7 @@ pub struct Args {
}
pub async fn query(args: Args, client: &QueryClientWithNyxd) {
match client.get_all_cached_described_nodes_v2().await {
match client.get_all_cached_described_nodes().await {
Ok(res) => match args.identity_key {
Some(identity_key) => {
let node = res.iter().find(|node| {
+2 -4
View File
@@ -1,11 +1,9 @@
[package]
name = "nym-config"
version.workspace = true
version = "0.1.0"
authors = ["Jedrzej Stuczynski <andrew@nymtech.net>"]
edition = "2021"
license.workspace = true
homepage.workspace = true
description = "Config related helpers and functions"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -18,7 +16,7 @@ thiserror = { workspace = true }
toml = { workspace = true, features = ["display"] }
url = { workspace = true }
nym-network-defaults = { workspace = true, features = ["utoipa"] }
nym-network-defaults = { path = "../network-defaults", features = ["utoipa"] }
[features]
default = ["dirs"]
@@ -1,12 +1,8 @@
[package]
name = "nym-coconut-dkg-common"
version.workspace = true
version = "0.1.0"
edition = "2021"
license.workspace = true
description = "Common crate for Nym's DKG cosmwasm contract"
repository.workspace = true
homepage.workspace = true
documentation.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -17,8 +13,8 @@ cw-utils = { workspace = true }
cw2 = { workspace = true }
cw4 = { workspace = true }
nym-contracts-common = { workspace = true }
nym-multisig-contract-common = { workspace = true }
contracts-common = { path = "../contracts-common", package = "nym-contracts-common" }
nym-multisig-contract-common = { path = "../multisig-contract" }
[features]
schema = []
@@ -2,9 +2,9 @@
// SPDX-License-Identifier: Apache-2.0
use crate::types::{ChunkIndex, DealingIndex, EpochId, PartialContractDealingData};
use contracts_common::dealings::ContractSafeBytes;
use cosmwasm_schema::cw_serde;
use cosmwasm_std::Addr;
use nym_contracts_common::dealings::ContractSafeBytes;
use std::collections::{BTreeMap, HashMap};
/// Defines the maximum size of a dealing chunk. Currently set to 2kB
@@ -6,8 +6,8 @@ use crate::types::{
ChunkIndex, DealingIndex, EncodedBTEPublicKeyWithProof, EpochId, TimeConfiguration,
};
use crate::verification_key::VerificationKeyShare;
use contracts_common::IdentityKey;
use cosmwasm_schema::cw_serde;
use nym_contracts_common::IdentityKey;
#[cfg(feature = "schema")]
use crate::{
@@ -6,9 +6,9 @@ use std::fmt::{Display, Formatter};
use std::str::FromStr;
pub use crate::dealer::{DealerDetails, DealerRegistrationDetails, PagedDealerResponse};
pub use contracts_common::dealings::ContractSafeBytes;
pub use cosmwasm_std::{Addr, Coin, Timestamp};
pub use cw4::Cw4Contract;
pub use nym_contracts_common::dealings::ContractSafeBytes;
pub type EncodedBTEPublicKeyWithProof = String;
pub type EncodedBTEPublicKeyWithProofRef<'a> = &'a str;
@@ -1,6 +1,6 @@
[package]
name = "nym-contracts-common-testing"
version.workspace = true
version = "0.1.0"
authors.workspace = true
repository.workspace = true
homepage.workspace = true
@@ -9,7 +9,6 @@ edition.workspace = true
license.workspace = true
rust-version.workspace = true
readme.workspace = true
description = "Common crate for cosmwasm contract tests"
[dependencies]
anyhow = { workspace = true }
@@ -21,7 +20,7 @@ rand_chacha = { workspace = true }
rand = { workspace = true }
cw-multi-test = { workspace = true }
nym-contracts-common = { workspace = true }
nym-contracts-common = { path = "../contracts-common" }
[lints]
workspace = true
@@ -1,6 +1,6 @@
[package]
name = "nym-contracts-common"
version.workspace = true
version = "0.5.0"
description = "Common library for Nym cosmwasm contracts"
edition = { workspace = true }
authors = { workspace = true }
@@ -1,6 +1,6 @@
[package]
name = "easy-addr"
version.workspace = true
version = "0.1.0"
edition = "2021"
publish = false
license.workspace = true
@@ -11,4 +11,4 @@ proc-macro = true
[dependencies]
cosmwasm-std = { workspace = true }
quote = { workspace = true }
syn = { workspace = true, features = ["full", "printing", "extra-traits"] }
syn = { workspace = true, features = ["full", "printing", "extra-traits"] }
@@ -1,12 +1,8 @@
[package]
name = "nym-ecash-contract-common"
version.workspace = true
version = "0.1.0"
edition = "2021"
license.workspace = true
description = "Common crate for Nym's ecash/zknym cosmwasm contract"
repository.workspace = true
homepage.workspace = true
documentation.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -15,7 +11,7 @@ bs58.workspace = true
cosmwasm-std = { workspace = true }
cosmwasm-schema = { workspace = true }
cw2 = { workspace = true, optional = true }
nym-multisig-contract-common = { workspace = true }
nym-multisig-contract-common = { path = "../multisig-contract" }
thiserror.workspace = true
cw-utils = { workspace = true }
cw-controllers = { workspace = true }
@@ -1,12 +1,8 @@
[package]
name = "nym-group-contract-common"
version.workspace = true
version = "0.1.0"
edition = "2021"
license.workspace = true
description = "Common crate for Nym's group cosmwasm contract"
repository.workspace = true
homepage.workspace = true
documentation.workspace = true
[dependencies]
cosmwasm-schema = { workspace = true }
@@ -1,6 +1,6 @@
[package]
name = "nym-mixnet-contract-common"
version.workspace = true
version = "0.6.0"
description = "Common library for the Nym mixnet contract"
rust-version = "1.85"
edition = { workspace = true }
@@ -22,7 +22,7 @@ semver = { workspace = true, features = ["serde"] }
# we still have to preserve that import for `JsonSchema` for `Layer` type (since we can't use cw_serde macro due to custom serde impl)
schemars = { workspace = true }
thiserror = { workspace = true }
nym-contracts-common = { workspace = true }
contracts-common = { path = "../contracts-common", package = "nym-contracts-common", version = "0.5.0" }
humantime-serde = { workspace = true }
utoipa = { workspace = true, optional = true }
@@ -41,4 +41,4 @@ schema = ["cw2"]
generate-ts = ['ts-rs']
[lints]
workspace = true
workspace = true
@@ -5,10 +5,10 @@ use crate::nym_node::Role;
use crate::{
EpochEventId, EpochState, IntervalEventId, NodeId, OperatingCostRange, ProfitMarginRange,
};
use contracts_common::Percent;
use contracts_common::signing::verifier::ApiVerifierError;
use cosmwasm_std::{Addr, Coin, Decimal, Uint128};
use cw_controllers::AdminError;
use nym_contracts_common::Percent;
use nym_contracts_common::signing::verifier::ApiVerifierError;
use thiserror::Error;
#[derive(Error, Debug, PartialEq)]
@@ -8,8 +8,8 @@ use crate::nym_node::Role;
use crate::reward_params::{ActiveSetUpdate, IntervalRewardParams, IntervalRewardingParamsUpdate};
use crate::rewarding::RewardDistribution;
use crate::{BlockHeight, ContractStateParamsUpdate, EpochId, IdentityKeyRef, Interval, NodeId};
pub use contracts_common::events::*;
use cosmwasm_std::{Addr, Coin, Decimal, Event, attr};
pub use nym_contracts_common::events::*;
use std::fmt::Display;
pub const EVENT_VERSION_PREFIX: &str = "v2_";
@@ -7,8 +7,8 @@ use crate::{
EpochEventId, IntervalEventId, MixNodeBond, MixNodeDetails, NodeId, NodeRewarding, NymNodeBond,
NymNodeDetails, PendingNodeChanges,
};
use contracts_common::IdentityKeyRef;
use cosmwasm_std::{Coin, Decimal, StdError, StdResult, Uint128};
use nym_contracts_common::IdentityKeyRef;
#[track_caller]
pub fn compare_decimals(a: Decimal, b: Decimal, epsilon: Option<Decimal>) {
@@ -21,6 +21,7 @@ pub mod types;
pub use config_score::*;
pub use constants::*;
pub use contracts_common::types::*;
pub use cosmwasm_std::{Addr, Coin, Decimal, Fraction};
pub use delegation::{
Delegation, PagedAllDelegationsResponse, PagedDelegatorDelegationsResponse,
@@ -40,7 +41,6 @@ pub use mixnode::{
NodeRewarding, PagedMixnodeBondsResponse, UnbondedMixnode,
};
pub use msg::*;
pub use nym_contracts_common::types::*;
pub use nym_node::{NymNode, NymNodeBond, NymNodeDetails, PendingNodeChanges};
pub use pending_events::{
EpochEventId, IntervalEventId, NumberOfPendingEventsResponse, PendingEpochEvent,
@@ -18,9 +18,9 @@ use crate::{
VersionScoreFormulaParams,
};
use crate::{OperatingCostRange, ProfitMarginRange};
use contracts_common::{IdentityKey, Percent, signing::MessageSignature};
use cosmwasm_schema::cw_serde;
use cosmwasm_std::{Coin, Decimal};
use nym_contracts_common::{IdentityKey, Percent, signing::MessageSignature};
use std::time::Duration;
#[cfg(feature = "schema")]
@@ -55,9 +55,9 @@ use crate::{
types::{ContractState, ContractStateParams},
};
#[cfg(feature = "schema")]
use cosmwasm_schema::QueryResponses;
use contracts_common::{ContractBuildInformation, signing::Nonce};
#[cfg(feature = "schema")]
use nym_contracts_common::{ContractBuildInformation, signing::Nonce};
use cosmwasm_schema::QueryResponses;
#[cw_serde]
pub struct InstantiateMsg {
@@ -3,10 +3,10 @@
use crate::error::MixnetContractError;
use crate::{EpochEventId, EpochId, Gateway, IntervalEventId, MixNode, NodeId, NodeRewarding};
use contracts_common::IdentityKey;
use cosmwasm_schema::cw_serde;
use cosmwasm_std::{Addr, Coin, Decimal, StdError, StdResult};
use cw_storage_plus::{IntKey, Key, KeyDeserialize, PrimaryKey};
use nym_contracts_common::IdentityKey;
use std::fmt::{Display, Formatter};
#[cw_serde]
@@ -1,8 +1,8 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use contracts_common::truncate_decimal;
use cosmwasm_std::{Coin, Decimal, Uint128};
use nym_contracts_common::truncate_decimal;
/// Truncates all decimal points so that the reward would fit in a `Coin` and so that we would
/// never attempt to reward more than the owner is due
@@ -3,11 +3,11 @@
use crate::nym_node::NymNode;
use crate::{Gateway, MixNode, NodeCostParams};
use cosmwasm_std::{Addr, Coin};
use nym_contracts_common::signing::{
use contracts_common::signing::{
ContractMessageContent, LegacyContractMessageContent, MessageType, Nonce, SignableMessage,
SigningPurpose,
};
use cosmwasm_std::{Addr, Coin};
use serde::Serialize;
pub type SignableMixNodeBondingMsg = SignableMessage<ContractMessageContent<MixnodeBondingPayload>>;
@@ -5,10 +5,10 @@ use crate::EpochId;
use crate::config_score::{ConfigScoreParams, OutdatedVersionWeights, VersionScoreFormulaParams};
use crate::nym_node::Role;
use crate::reward_params::RewardedSetParams;
use contracts_common::Percent;
use cosmwasm_schema::cw_serde;
use cosmwasm_std::Coin;
use cosmwasm_std::{Addr, Uint128};
use nym_contracts_common::Percent;
use std::fmt::{Display, Formatter};
// type aliases for better reasoning about available data
@@ -1,10 +1,8 @@
[package]
name = "nym-multisig-contract-common"
version.workspace = true
version = "0.1.0"
edition = "2021"
license.workspace = true
description = "Common code for the Nym multisig CosmWasm smart contract"
homepage.workspace = true
[dependencies]
cosmwasm-schema = { workspace = true }
@@ -1,6 +1,6 @@
[package]
name = "nym-performance-contract-common"
version.workspace = true
version = "0.1.0"
authors.workspace = true
repository.workspace = true
homepage.workspace = true
@@ -9,7 +9,6 @@ edition.workspace = true
license.workspace = true
rust-version.workspace = true
readme.workspace = true
description = "Common crate for Nym's group performance contract"
[dependencies]
thiserror = { workspace = true }
@@ -20,7 +19,7 @@ cosmwasm-std = { workspace = true }
cosmwasm-schema = { workspace = true }
cw-controllers = { workspace = true }
nym-contracts-common = { workspace = true }
nym-contracts-common = { path = "../contracts-common" }
[features]
@@ -1,6 +1,6 @@
[package]
name = "nym-pool-contract-common"
version.workspace = true
version = "0.1.0"
description = "Common library for the Nym Pool contract"
authors.workspace = true
repository.workspace = true
@@ -1,6 +1,6 @@
[package]
name = "nym-vesting-contract-common"
version.workspace = true
version = "0.7.0"
description = "Common library for the Nym vesting contract"
edition = { workspace = true }
authors = { workspace = true }
@@ -11,8 +11,8 @@ repository = { workspace = true }
cosmwasm-std = { workspace = true }
cosmwasm-schema = { workspace = true }
cw2 = { workspace = true, optional = true }
nym-mixnet-contract-common = { workspace = true }
nym-contracts-common = { workspace = true }
mixnet-contract-common = { path = "../mixnet-contract", package = "nym-mixnet-contract-common", version = "0.6.0" }
contracts-common = { path = "../contracts-common", package = "nym-contracts-common", version = "0.5.0" }
serde = { workspace = true, features = ["derive"] }
thiserror = { workspace = true }
# without this feature, cargo clippy emits a ton of incompatibility warnings
@@ -3,7 +3,7 @@
use crate::account::VestingAccountStorageKey;
use cosmwasm_std::{Addr, Coin, OverflowError, StdError, Uint128};
use nym_mixnet_contract_common::NodeId;
use mixnet_contract_common::NodeId;
use thiserror::Error;
#[derive(Error, Debug, PartialEq)]
@@ -6,7 +6,7 @@
use cosmwasm_schema::cw_serde;
use cosmwasm_std::{Addr, Coin};
use nym_mixnet_contract_common::NodeId;
use mixnet_contract_common::NodeId;
pub mod account;
pub mod error;
@@ -126,8 +126,8 @@ pub struct AccountsResponse {
#[cfg(test)]
mod test {
use contracts_common::Percent;
use cosmwasm_std::Uint128;
use nym_contracts_common::Percent;
use std::str::FromStr;
use crate::PledgeCap;
@@ -2,19 +2,19 @@
// SPDX-License-Identifier: Apache-2.0
use crate::{PledgeCap, VestingSpecification};
use contracts_common::signing::MessageSignature;
use cosmwasm_schema::cw_serde;
use cosmwasm_std::{Coin, Timestamp};
use nym_contracts_common::signing::MessageSignature;
use nym_mixnet_contract_common::{
use mixnet_contract_common::{
Gateway, MixNode, NodeId,
gateway::GatewayConfigUpdate,
mixnode::{MixNodeConfigUpdate, NodeCostParams},
};
#[cfg(feature = "schema")]
use cosmwasm_schema::QueryResponses;
use contracts_common::ContractBuildInformation;
#[cfg(feature = "schema")]
use nym_contracts_common::ContractBuildInformation;
use cosmwasm_schema::QueryResponses;
#[cfg(feature = "schema")]
use crate::{
@@ -1,10 +1,10 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use contracts_common::Percent;
use cosmwasm_schema::cw_serde;
use cosmwasm_std::{Coin, Timestamp, Uint128};
use nym_contracts_common::Percent;
use nym_mixnet_contract_common::NodeId;
use mixnet_contract_common::NodeId;
use std::str::FromStr;
#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))]
+11 -12
View File
@@ -1,6 +1,6 @@
[package]
name = "nym-credential-proxy-lib"
version.workspace = true
version = "0.1.0"
authors.workspace = true
repository.workspace = true
homepage.workspace = true
@@ -9,7 +9,6 @@ edition.workspace = true
license.workspace = true
rust-version.workspace = true
readme.workspace = true
description = "Build script and core functionality of the Nym Credential Proxy"
[dependencies]
anyhow = { workspace = true }
@@ -34,16 +33,16 @@ uuid = { workspace = true, features = ["serde"] }
url = { workspace = true }
zeroize = { workspace = true }
nym-credentials = { workspace = true }
nym-crypto = { workspace = true, features = ["asymmetric", "rand", "serde"] }
nym-credentials-interface = { workspace = true }
nym-credential-proxy-requests = { workspace = true, features = ["query-types"] }
nym-ecash-signer-check = { workspace = true }
nym-ecash-contract-common = { workspace = true }
nym-compact-ecash = { workspace = true }
nym-validator-client = { workspace = true }
nym-network-defaults = { workspace = true }
nym-cache = { workspace = true }
nym-credentials = { path = "../credentials" }
nym-crypto = { path = "../crypto", features = ["asymmetric", "rand", "serde"] }
nym-credentials-interface = { path = "../credentials-interface" }
nym-credential-proxy-requests = { path = "../../nym-credential-proxy/nym-credential-proxy-requests" }
nym-ecash-signer-check = { path = "../ecash-signer-check" }
nym-ecash-contract-common = { path = "../cosmwasm-smart-contracts/ecash-contract" }
nym-compact-ecash = { path = "../nym_offline_compact_ecash" }
nym-validator-client = { path = "../client-libs/validator-client" }
nym-network-defaults = { path = "../network-defaults" }
nym-cache = { path = "../nym-cache" }
[dev-dependencies]
tempfile = { workspace = true }
+10 -14
View File
@@ -1,13 +1,9 @@
[package]
name = "nym-credential-storage"
version.workspace = true
version = "0.1.0"
edition = "2021"
license.workspace = true
rust-version.workspace = true
description = "Crate for handling and storing spent and unspent zknym ticketbooks"
repository.workspace = true
homepage.workspace = true
documentation.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -22,12 +18,12 @@ time = { workspace = true }
tokio = { workspace = true, features = ["sync"] }
zeroize = { workspace = true, features = ["zeroize_derive"] }
nym-credentials = { workspace = true }
nym-compact-ecash = { workspace = true }
nym-ecash-time = { workspace = true }
nym-credentials = { path = "../credentials" }
nym-compact-ecash = { path = "../nym_offline_compact_ecash" }
nym-ecash-time = { path = "../ecash-time" }
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.nym-sqlx-pool-guard]
workspace = true
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.sqlx-pool-guard]
path = "../../sqlx-pool-guard"
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.sqlx]
workspace = true
@@ -40,10 +36,10 @@ features = ["rt-multi-thread", "net", "signal", "fs"]
[dev-dependencies]
anyhow = { workspace = true }
nym-crypto = { workspace = true, features = ["asymmetric", "rand"] }
nym-test-utils = { workspace = true }
nym-credentials-interface = { workspace = true }
nym-compact-ecash = { workspace = true }
nym-crypto = { path = "../crypto", features = ["asymmetric", "rand"] }
nym-test-utils = { path = "../test-utils" }
nym-credentials-interface = { path = "../credentials-interface" }
nym-compact-ecash = { path = "../nym_offline_compact_ecash" }
[build-dependencies]
@@ -7,8 +7,8 @@ use crate::models::{
StoredIssuedTicketbook, StoredPendingTicketbook,
};
use nym_ecash_time::Date;
use nym_sqlx_pool_guard::SqlitePoolGuard;
use sqlx::{Executor, Sqlite, Transaction};
use sqlx_pool_guard::SqlitePoolGuard;
#[derive(Clone)]
pub struct SqliteEcashTicketbookManager {
@@ -34,11 +34,11 @@ use nym_credentials::{
IssuanceTicketBook, IssuedTicketBook,
};
use nym_ecash_time::{ecash_today, Date, EcashTime};
use nym_sqlx_pool_guard::SqlitePoolGuard;
use sqlx::{
sqlite::{SqliteAutoVacuum, SqliteSynchronous},
ConnectOptions,
};
use sqlx_pool_guard::SqlitePoolGuard;
use std::path::Path;
use zeroize::Zeroizing;
+10 -13
View File
@@ -1,12 +1,9 @@
[package]
name = "nym-credential-utils"
version.workspace = true
version = "0.1.0"
edition = "2021"
license.workspace = true
description = "Utils crate for dealing with zknym credentials"
repository.workspace = true
homepage.workspace = true
documentation.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
@@ -15,11 +12,11 @@ thiserror = { workspace = true }
tokio = { workspace = true }
time.workspace = true
nym-bandwidth-controller = { workspace = true }
nym-credentials = { workspace = true }
nym-credentials-interface = { workspace = true }
nym-credential-storage = { workspace = true, features = ["persistent-storage"] }
nym-validator-client = { workspace = true }
nym-config = { workspace = true }
nym-client-core = { workspace = true }
nym-ecash-time = { workspace = true }
nym-bandwidth-controller = { path = "../../common/bandwidth-controller" }
nym-credentials = { path = "../../common/credentials" }
nym-credentials-interface = { path = "../../common/credentials-interface" }
nym-credential-storage = { path = "../../common/credential-storage", features = ["persistent-storage"] }
nym-validator-client = { path = "../../common/client-libs/validator-client" }
nym-config = { path = "../../common/config" }
nym-client-core = { path = "../../common/client-core" }
nym-ecash-time = { path = "../../common/ecash-time" }
+11 -13
View File
@@ -1,6 +1,6 @@
[package]
name = "nym-credential-verification"
version.workspace = true
version = "0.1.0"
authors.workspace = true
repository.workspace = true
homepage.workspace = true
@@ -9,7 +9,6 @@ edition.workspace = true
license.workspace = true
rust-version.workspace = true
readme.workspace = true
description = "Store and verify zknym credentials"
[dependencies]
async-trait = { workspace = true }
@@ -24,14 +23,13 @@ tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
time = { workspace = true }
tracing = { workspace = true }
nym-api-requests = { workspace = true }
nym-credentials = { workspace = true }
nym-credentials-interface = { workspace = true }
nym-crypto = { workspace = true, features = ["asymmetric"] }
nym-ecash-contract-common = { workspace = true }
nym-gateway-requests = { workspace = true }
nym-gateway-storage = { workspace = true }
nym-metrics = { workspace = true }
nym-task = { workspace = true }
nym-validator-client = { workspace = true, features = ["http-client"] }
nym-upgrade-mode-check = { workspace = true }
nym-api-requests = { path = "../../nym-api/nym-api-requests" }
nym-credentials = { path = "../credentials" }
nym-credentials-interface = { path = "../credentials-interface" }
nym-crypto = { path = "../crypto", features = ["asymmetric"] }
nym-ecash-contract-common = { path = "../cosmwasm-smart-contracts/ecash-contract" }
nym-gateway-requests = { path = "../gateway-requests" }
nym-gateway-storage = { path = "../gateway-storage" }
nym-task = { path = "../task" }
nym-validator-client = { path = "../client-libs/validator-client" }
nym-upgrade-mode-check = { path = "../upgrade-mode-check" }
@@ -59,13 +59,9 @@ impl traits::EcashManager for EcashManager {
.verify(aggregated_verification_key)
.map_err(|err| match err {
CompactEcashError::ExpirationDateSignatureValidity => {
nym_metrics::inc!("ecash_verification_failures_invalid_date_signature");
EcashTicketError::MalformedTicketInvalidDateSignatures
}
_ => {
nym_metrics::inc!("ecash_verification_failures_signature");
EcashTicketError::MalformedTicket
}
_ => EcashTicketError::MalformedTicket,
})?;
self.insert_pay_info(credential.pay_info.into(), insert_index)
@@ -174,14 +170,14 @@ impl EcashManager {
}
pub struct MockEcashManager {
verification_key: tokio::sync::RwLock<VerificationKeyAuth>,
verfication_key: tokio::sync::RwLock<VerificationKeyAuth>,
storage: Box<dyn BandwidthGatewayStorage + Send + Sync>,
}
impl MockEcashManager {
pub fn new(storage: Box<dyn BandwidthGatewayStorage + Send + Sync>) -> Self {
Self {
verification_key: tokio::sync::RwLock::new(
verfication_key: tokio::sync::RwLock::new(
VerificationKeyAuth::from_bytes(&[
129, 187, 76, 12, 1, 51, 46, 26, 132, 205, 148, 109, 140, 131, 50, 119, 45,
128, 51, 218, 106, 70, 181, 74, 244, 38, 162, 62, 42, 12, 5, 100, 7, 136, 32,
@@ -237,7 +233,7 @@ impl traits::EcashManager for MockEcashManager {
&self,
_epoch_id: EpochId,
) -> Result<RwLockReadGuard<'_, VerificationKeyAuth>, EcashTicketError> {
Ok(self.verification_key.read().await)
Ok(self.verfication_key.read().await)
}
fn storage(&self) -> Box<dyn BandwidthGatewayStorage + Send + Sync> {
@@ -253,8 +249,4 @@ impl traits::EcashManager for MockEcashManager {
}
fn async_verify(&self, _ticket: ClientTicket) {}
fn is_mock(&self) -> bool {
true
}
}
@@ -222,13 +222,9 @@ impl SharedState {
RwLockReadGuard::try_map(guard, |data| data.get(&epoch_id).map(|d| &d.master_key))
{
trace!("we already had cached api clients for epoch {epoch_id}");
nym_metrics::inc!("ecash_verification_key_cache_hits");
return Ok(mapped);
}
// Cache miss - need to fetch and set epoch data
nym_metrics::inc!("ecash_verification_key_cache_misses");
let write_guard = self.set_epoch_data(epoch_id).await?;
let guard = write_guard.downgrade();
@@ -20,10 +20,4 @@ pub trait EcashManager {
aggregated_verification_key: &VerificationKeyAuth,
) -> Result<(), EcashTicketError>;
fn async_verify(&self, ticket: ClientTicket);
/// Returns true if this is a mock ecash manager (for local testing).
/// Default implementation returns false.
fn is_mock(&self) -> bool {
false
}
}
+2 -37
View File
@@ -8,7 +8,6 @@ use nym_credentials::ecash::utils::{EcashTime, cred_exp_date, ecash_today};
use nym_credentials_interface::{Bandwidth, ClientTicket, TicketType};
use nym_gateway_requests::models::CredentialSpendingRequest;
use std::sync::Arc;
use std::time::Instant;
use time::{Date, OffsetDateTime};
use tracing::*;
@@ -22,10 +21,6 @@ pub mod ecash;
pub mod error;
pub mod upgrade_mode;
// Histogram buckets for ecash verification duration (in seconds)
const ECASH_VERIFICATION_DURATION_BUCKETS: &[f64] =
&[0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1.0, 2.0, 5.0];
pub struct CredentialVerifier {
credential: CredentialSpendingRequest,
ecash_verifier: Arc<dyn EcashManager + Send + Sync>,
@@ -69,7 +64,6 @@ impl CredentialVerifier {
.await?;
if spent {
trace!("the credential has already been spent before at this gateway");
nym_metrics::inc!("ecash_verification_failures_double_spending");
return Err(Error::BandwidthCredentialAlreadySpent);
}
Ok(())
@@ -111,9 +105,6 @@ impl CredentialVerifier {
}
pub async fn verify(&mut self) -> Result<i64> {
let start = Instant::now();
nym_metrics::inc!("ecash_verification_attempts");
let received_at = OffsetDateTime::now_utc();
let spend_date = ecash_today();
@@ -122,39 +113,15 @@ impl CredentialVerifier {
let credential_type = TicketType::try_from_encoded(self.credential.data.payment.t_type)?;
if self.credential.data.payment.spend_value != 1 {
nym_metrics::inc!("ecash_verification_failures_multiple_tickets");
return Err(Error::MultipleTickets);
}
if let Err(e) = self.check_credential_spending_date(spend_date.ecash_date()) {
nym_metrics::inc!("ecash_verification_failures_invalid_spend_date");
return Err(e);
}
self.check_credential_spending_date(spend_date.ecash_date())?;
self.check_local_db_for_double_spending(&serial_number)
.await?;
// TODO: do we HAVE TO do it?
let verify_result = self.cryptographically_verify_ticket().await;
// Track verification duration
let duration = start.elapsed().as_secs_f64();
nym_metrics::add_histogram_obs!(
"ecash_verification_duration_seconds",
duration,
ECASH_VERIFICATION_DURATION_BUCKETS
);
// Track epoch ID - use dynamic metric name via registry
let epoch_id = self.credential.data.epoch_id;
let epoch_metric = format!(
"nym_credential_verification_ecash_epoch_{}_verifications",
epoch_id
);
nym_metrics::metrics_registry().maybe_register_and_inc(&epoch_metric, None);
// Check verification result after timing
verify_result?;
self.cryptographically_verify_ticket().await?;
let ticket_id = self.store_received_ticket(received_at).await?;
self.async_verify_ticket(ticket_id);
@@ -168,8 +135,6 @@ impl CredentialVerifier {
.increase_bandwidth(bandwidth, cred_exp_date())
.await?;
nym_metrics::inc!("ecash_verification_success");
Ok(self
.bandwidth_storage_manager
.client_bandwidth
+7 -7
View File
@@ -1,18 +1,17 @@
[package]
name = "nym-credentials-interface"
version.workspace = true
version = "0.1.0"
authors.workspace = true
repository.workspace = true
homepage.workspace = true
documentation.workspace = true
edition.workspace = true
license.workspace = true
description = "Interface for Nym's compact eacash / zknym credential scheme"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
nym-bls12_381-fork = { workspace = true }
bls12_381 = { workspace = true, default-features = false }
serde = { workspace = true, features = ["derive"] }
thiserror = { workspace = true }
strum = { workspace = true, features = ["derive"] }
@@ -21,7 +20,8 @@ time = { workspace = true, features = ["serde"] }
utoipa = { workspace = true }
rand = { workspace = true }
nym-compact-ecash = { workspace = true }
nym-ecash-time = { workspace = true }
nym-network-defaults = { workspace = true }
nym-upgrade-mode-check = { workspace = true }
nym-compact-ecash = { path = "../nym_offline_compact_ecash" }
nym-ecash-time = { path = "../ecash-time" }
nym-network-defaults = { path = "../network-defaults" }
nym-upgrade-mode-check = { path = "../upgrade-mode-check" }
+1 -16
View File
@@ -3,7 +3,6 @@
use rand::Rng;
use serde::{Deserialize, Serialize};
use std::fmt::Debug;
use thiserror::Error;
use time::{Date, OffsetDateTime};
@@ -74,7 +73,7 @@ pub struct CredentialSigningData {
pub ticketbook_type: TicketType,
}
#[derive(Serialize, Deserialize, PartialEq, Clone)]
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
pub struct CredentialSpendingData {
pub payment: Payment,
@@ -87,20 +86,6 @@ pub struct CredentialSpendingData {
pub epoch_id: u64,
}
impl Debug for CredentialSpendingData {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
// we're redacting the payment not since it contains secret,
// but because it's producing a lot of noise in the output and
// we are not really interested in coordinates of each of the attached curve points
f.debug_struct("CredentialSpendingData")
.field("payment", &"[REDACTED]")
.field("pay_info", &self.pay_info)
.field("spend_date", &self.spend_date)
.field("epoch_id", &self.epoch_id)
.finish()
}
}
impl CredentialSpendingData {
pub fn verify(&self, verification_key: &VerificationKeyAuth) -> Result<(), CompactEcashError> {
self.payment.spend_verify(
+12 -15
View File
@@ -1,17 +1,13 @@
[package]
name = "nym-credentials"
version.workspace = true
version = "0.1.0"
edition = "2021"
license.workspace = true
description = "Crate for using Nym's zknym credentials"
repository.workspace = true
homepage.workspace = true
documentation.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
nym-bls12_381-fork = { workspace = true, default-features = false, features = ["pairings", "alloc", "experimental"] }
bls12_381 = { workspace = true, default-features = false, features = ["pairings", "alloc", "experimental"] }
bincode = { workspace = true }
cosmrs = { workspace = true }
thiserror = { workspace = true }
@@ -20,17 +16,18 @@ time = { workspace = true, features = ["serde"] }
serde = { workspace = true, features = ["derive"] }
zeroize = { workspace = true }
nym-ecash-time = { workspace = true, features = ["expiration"] }
nym-ecash-time = { path = "../ecash-time", features = ["expiration"] }
# I guess temporarily until we get serde support in coconut up and running
nym-credentials-interface = { workspace = true }
nym-crypto = { workspace = true }
nym-api-requests = { workspace = true }
nym-http-api-client = { workspace = true }
nym-validator-client = { workspace = true, default-features = false }
nym-ecash-contract-common = { workspace = true }
nym-network-defaults = { workspace = true }
nym-serde-helpers = { workspace = true, features = ["date"] }
nym-credentials-interface = { path = "../credentials-interface" }
nym-crypto = { path = "../crypto" }
nym-api-requests = { path = "../../nym-api/nym-api-requests" }
nym-http-api-client = { path = "../http-api-client" }
nym-validator-client = { path = "../client-libs/validator-client", default-features = false }
nym-ecash-contract-common = { path = "../cosmwasm-smart-contracts/ecash-contract" }
nym-network-defaults = { path = "../network-defaults" }
nym-serde-helpers = { path = "../serde-helpers", features = ["date"] }
[dev-dependencies]
rand = { workspace = true }
+7 -8
View File
@@ -1,6 +1,6 @@
[package]
name = "nym-crypto"
version.workspace = true
version = "0.4.0"
description = "Crypto library for the nym mixnet"
edition = { workspace = true }
authors = { workspace = true }
@@ -15,7 +15,6 @@ base64.workspace = true
bs58 = { workspace = true }
blake3 = { workspace = true, features = ["traits-preview"], optional = true }
ctr = { workspace = true, optional = true }
curve25519-dalek = { workspace = true, optional = true }
digest = { workspace = true, optional = true }
generic-array = { workspace = true, optional = true }
hkdf = { workspace = true, optional = true }
@@ -33,14 +32,14 @@ thiserror = { workspace = true }
zeroize = { workspace = true, optional = true, features = ["zeroize_derive"] }
# internal
nym-sphinx-types = { workspace = true }
nym-pemstore = { workspace = true }
nym-sphinx-types = { path = "../nymsphinx/types", version = "0.2.0", default-features = false }
nym-pemstore = { path = "../../common/pemstore", version = "0.3.0" }
[dev-dependencies]
anyhow = { workspace = true }
rand_chacha = { workspace = true }
serde_json = { workspace = true }
nym-test-utils = { workspace = true }
nym-test-utils = { path = "../test-utils" }
[features]
@@ -48,10 +47,10 @@ default = []
aead = ["dep:aead", "aead/std", "aes-gcm-siv", "generic-array"]
naive_jwt = ["asymmetric", "jwt-simple"]
serde = ["dep:serde", "serde_bytes", "ed25519-dalek/serde", "x25519-dalek/serde"]
asymmetric = ["x25519-dalek", "ed25519-dalek", "curve25519-dalek", "sha2", "zeroize"]
hashing = ["blake3", "digest", "hkdf", "hmac", "generic-array", "sha2", "zeroize"]
asymmetric = ["x25519-dalek", "ed25519-dalek", "zeroize"]
hashing = ["blake3", "digest", "hkdf", "hmac", "generic-array", "sha2"]
stream_cipher = ["aes", "ctr", "cipher", "generic-array"]
sphinx = ["nym-sphinx-types/sphinx"]
[lints]
workspace = true
workspace = true
+3 -115
View File
@@ -20,7 +20,6 @@ pub use serde_helpers::*;
#[cfg(feature = "sphinx")]
use nym_sphinx_types::{DESTINATION_ADDRESS_LENGTH, DestinationAddressBytes};
use crate::asymmetric::x25519;
#[cfg(feature = "rand")]
use rand::{CryptoRng, Rng, RngCore};
#[cfg(feature = "serde")]
@@ -111,18 +110,6 @@ impl KeyPair {
index: fake_index(pub_bytes),
})
}
/// Converts this Ed25519 keypair to an X25519 keypair for ECDH.
///
/// Uses the standard ed25519→x25519 conversion via SHA-512 hash and clamping.
/// This is the same approach as libsodium's `crypto_sign_ed25519_sk_to_curve25519`.
///
/// # Returns
/// The converted X25519 keypair
pub fn to_x25519(&self) -> x25519::KeyPair {
let private_key = self.private_key.to_x25519();
x25519::KeyPair::from(private_key)
}
}
/// Reduces a byte slice into a u32 value by XOR-ing all its bytes into a 4-byte accumulator.
@@ -149,16 +136,6 @@ impl From<PrivateKey> for KeyPair {
}
}
impl From<(PrivateKey, PublicKey)> for KeyPair {
fn from((private_key, public_key): (PrivateKey, PublicKey)) -> Self {
KeyPair {
private_key,
public_key,
index: fake_index(public_key.to_bytes().as_ref()),
}
}
}
impl PemStorableKeyPair for KeyPair {
type PrivatePemKey = PrivateKey;
type PublicPemKey = PublicKey;
@@ -208,25 +185,14 @@ impl PublicKey {
}
/// Convert this public key to a byte array.
#[inline]
pub fn to_bytes(self) -> [u8; PUBLIC_KEY_LENGTH] {
self.0.to_bytes()
}
/// View this public key as a byte array.
#[inline]
pub fn as_bytes(&self) -> &[u8; PUBLIC_KEY_LENGTH] {
self.0.as_bytes()
}
#[inline]
pub fn from_bytes(b: &[u8]) -> Result<Self, Ed25519RecoveryError> {
Self::from_byte_array(b.try_into()?)
}
#[inline]
pub fn from_byte_array(b: &[u8; PUBLIC_KEY_LENGTH]) -> Result<Self, Ed25519RecoveryError> {
Ok(PublicKey(ed25519_dalek::VerifyingKey::from_bytes(b)?))
Ok(PublicKey(ed25519_dalek::VerifyingKey::from_bytes(
b.try_into()?,
)?))
}
pub fn to_base58_string(self) -> String {
@@ -247,37 +213,6 @@ impl PublicKey {
) -> Result<(), SignatureError> {
self.0.verify(message.as_ref(), &signature.0)
}
/// Converts this Ed25519 public key to an X25519 public key for ECDH.
///
/// Uses the standard ed25519→x25519 conversion by converting the Edwards point
/// to Montgomery form. This is the same approach as libsodium's
/// `crypto_sign_ed25519_pk_to_curve25519`.
///
/// # Returns
/// * `Ok(x25519::PublicKey)` - The converted X25519 public key
/// * `Err(Ed25519RecoveryError)` - If the conversion fails (e.g., low-order point)
pub fn to_x25519(&self) -> Result<crate::asymmetric::x25519::PublicKey, Ed25519RecoveryError> {
use curve25519_dalek::edwards::CompressedEdwardsY;
// Decompress the Ed25519 point
let compressed = CompressedEdwardsY((*self).to_bytes());
let edwards_point = compressed.decompress().ok_or_else(|| {
Ed25519RecoveryError::MalformedBytes(SignatureError::from_source(
"Failed to decompress Ed25519 point".to_string(),
))
})?;
// Convert to Montgomery form
let montgomery = edwards_point.to_montgomery();
// Create X25519 public key
crate::asymmetric::x25519::PublicKey::from_bytes(montgomery.as_bytes()).map_err(|_| {
Ed25519RecoveryError::MalformedBytes(SignatureError::from_source(
"Failed to convert to X25519".to_string(),
))
})
}
}
#[cfg(feature = "sphinx")]
@@ -399,30 +334,6 @@ impl PrivateKey {
let signature_bytes = self.sign(text).to_bytes();
bs58::encode(signature_bytes).into_string()
}
/// Converts this Ed25519 private key to an X25519 private key for ECDH.
///
/// Uses the standard ed25519→x25519 conversion via SHA-512 hash and clamping.
/// This is the same approach as libsodium's `crypto_sign_ed25519_sk_to_curve25519`.
///
/// # Returns
/// The converted X25519 private key
pub fn to_x25519(&self) -> crate::asymmetric::x25519::PrivateKey {
use sha2::{Digest, Sha512};
// Hash the Ed25519 secret key with SHA-512
// Both hash and x25519_bytes wrapped in Zeroizing to clear key material
let mut hash = zeroize::Zeroizing::new([0u8; 64]);
hash.copy_from_slice(&Sha512::digest(self.0));
// Take first 32 bytes (clamping is done automatically by x25519_dalek::StaticSecret)
let mut x25519_bytes = zeroize::Zeroizing::new([0u8; 32]);
x25519_bytes.copy_from_slice(&hash[..32]);
#[allow(clippy::expect_used)]
crate::asymmetric::x25519::PrivateKey::from_bytes(&*x25519_bytes)
.expect("x25519 key conversion should never fail")
}
}
#[cfg(feature = "serde")]
@@ -606,27 +517,4 @@ mod tests {
assert_eq!(sig1.to_vec(), sig2);
}
#[test]
#[cfg(feature = "rand")]
fn test_ed25519_to_x25519_ecdh() {
let mut rng = thread_rng();
// Create two ed25519 keypairs
let alice_ed = KeyPair::new(&mut rng);
let bob_ed = KeyPair::new(&mut rng);
// Convert to x25519
let alice_x25519_private = alice_ed.private_key().to_x25519();
let alice_x25519_public = alice_ed.public_key().to_x25519().unwrap();
let bob_x25519_private = bob_ed.private_key().to_x25519();
let bob_x25519_public = bob_ed.public_key().to_x25519().unwrap();
// Perform ECDH both ways
let alice_shared = alice_x25519_private.diffie_hellman(&bob_x25519_public);
let bob_shared = bob_x25519_private.diffie_hellman(&alice_x25519_public);
// Both should produce the same shared secret
assert_eq!(alice_shared, bob_shared);
}
}
+1 -45
View File
@@ -4,7 +4,6 @@
use base64::Engine;
use nym_pemstore::traits::{PemStorableKey, PemStorableKeyPair};
use std::fmt::{self, Debug, Display, Formatter};
use std::ops::Deref;
use std::str::FromStr;
use thiserror::Error;
use zeroize::{Zeroize, ZeroizeOnDrop};
@@ -57,15 +56,6 @@ pub struct KeyPair {
pub(crate) public_key: PublicKey,
}
impl Debug for KeyPair {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_struct("KeyPair")
.field("private_key", &"<redacted>")
.field("public_key", &self.public_key.to_base58_string())
.finish()
}
}
impl KeyPair {
#[cfg(feature = "rand")]
pub fn new<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
@@ -103,15 +93,6 @@ impl From<PrivateKey> for KeyPair {
}
}
impl From<(PrivateKey, PublicKey)> for KeyPair {
fn from((private_key, public_key): (PrivateKey, PublicKey)) -> Self {
KeyPair {
private_key,
public_key,
}
}
}
impl PemStorableKeyPair for KeyPair {
type PrivatePemKey = PrivateKey;
type PublicPemKey = PublicKey;
@@ -135,13 +116,6 @@ impl PemStorableKeyPair for KeyPair {
#[derive(PartialEq, Eq, Hash, Copy, Clone)]
pub struct PublicKey(x25519_dalek::PublicKey);
impl Deref for PublicKey {
type Target = x25519_dalek::PublicKey;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl Display for PublicKey {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
Display::fmt(&self.to_base58_string(), f)
@@ -155,17 +129,14 @@ impl Debug for PublicKey {
}
impl PublicKey {
#[inline]
pub fn to_bytes(self) -> [u8; PUBLIC_KEY_SIZE] {
*self.0.as_bytes()
}
#[inline]
pub fn as_bytes(&self) -> &[u8; PUBLIC_KEY_SIZE] {
self.0.as_bytes()
}
#[inline]
pub fn from_bytes(b: &[u8]) -> Result<Self, KeyRecoveryError> {
if b.len() != PUBLIC_KEY_SIZE {
return Err(KeyRecoveryError::InvalidSizePublicKey {
@@ -175,12 +146,7 @@ impl PublicKey {
}
let mut bytes = [0; PUBLIC_KEY_SIZE];
bytes.copy_from_slice(&b[..PUBLIC_KEY_SIZE]);
Ok(Self::from_byte_array(&bytes))
}
#[inline]
pub fn from_byte_array(b: &[u8; PUBLIC_KEY_SIZE]) -> Self {
Self(x25519_dalek::PublicKey::from(*b))
Ok(Self(x25519_dalek::PublicKey::from(bytes)))
}
pub fn to_base58_string(self) -> String {
@@ -208,12 +174,6 @@ impl PublicKey {
}
}
impl From<[u8; PUBLIC_KEY_SIZE]> for PublicKey {
fn from(bytes: [u8; PUBLIC_KEY_SIZE]) -> Self {
PublicKey(x25519_dalek::PublicKey::from(bytes))
}
}
impl FromStr for PublicKey {
type Err = KeyRecoveryError;
@@ -336,10 +296,6 @@ impl PrivateKey {
Ok(Self(x25519_dalek::StaticSecret::from(bytes)))
}
pub fn from_secret(secret: [u8; PRIVATE_KEY_SIZE]) -> Self {
Self(x25519_dalek::StaticSecret::from(secret))
}
pub fn to_base58_string(&self) -> String {
bs58::encode(&self.to_bytes()).into_string()
}
-98
View File
@@ -1,98 +0,0 @@
// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
//! Key Derivation Functions using Blake3.
/// Derives a 32-byte key using Blake3's key derivation mode.
///
/// Uses Blake3's built-in `derive_key` function with domain separation via context string.
///
/// # Arguments
/// * `context` - Context string for domain separation (e.g., "nym-lp-psk-v1")
/// * `key_material` - Input key material (shared secret from ECDH, etc.)
/// * `salt` - Additional salt for freshness (timestamp + nonce)
///
/// # Returns
/// 32-byte derived key suitable for use as PSK
///
/// # Example
/// ```ignore
/// let psk = derive_key_blake3("nym-lp-psk-v1", shared_secret.as_bytes(), &salt);
/// ```
pub fn derive_key_blake3(context: &str, key_material: &[u8], salt: &[u8]) -> [u8; 32] {
// Concatenate key_material and salt as input
let input = [key_material, salt].concat();
// Use Blake3's derive_key with context for domain separation
// blake3::derive_key returns [u8; 32] directly
blake3::derive_key(context, &input)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_deterministic_derivation() {
let context = "test-context";
let key_material = b"shared_secret_12345";
let salt = b"salt_67890";
let key1 = derive_key_blake3(context, key_material, salt);
let key2 = derive_key_blake3(context, key_material, salt);
assert_eq!(key1, key2, "Same inputs should produce same output");
}
#[test]
fn test_different_contexts_produce_different_keys() {
let key_material = b"shared_secret";
let salt = b"salt";
let key1 = derive_key_blake3("context1", key_material, salt);
let key2 = derive_key_blake3("context2", key_material, salt);
assert_ne!(
key1, key2,
"Different contexts should produce different keys"
);
}
#[test]
fn test_different_salts_produce_different_keys() {
let context = "test-context";
let key_material = b"shared_secret";
let key1 = derive_key_blake3(context, key_material, b"salt1");
let key2 = derive_key_blake3(context, key_material, b"salt2");
assert_ne!(key1, key2, "Different salts should produce different keys");
}
#[test]
fn test_different_key_material_produces_different_keys() {
let context = "test-context";
let salt = b"salt";
let key1 = derive_key_blake3(context, b"secret1", salt);
let key2 = derive_key_blake3(context, b"secret2", salt);
assert_ne!(
key1, key2,
"Different key material should produce different keys"
);
}
#[test]
fn test_output_length() {
let key = derive_key_blake3("test", b"key", b"salt");
assert_eq!(key.len(), 32, "Output should be exactly 32 bytes");
}
#[test]
fn test_empty_inputs() {
// Should not panic with empty inputs
let key = derive_key_blake3("test", b"", b"");
assert_eq!(key.len(), 32);
}
}
-2
View File
@@ -10,8 +10,6 @@ pub mod crypto_hash;
pub mod hkdf;
#[cfg(feature = "hashing")]
pub mod hmac;
#[cfg(feature = "hashing")]
pub mod kdf;
#[cfg(all(feature = "asymmetric", feature = "hashing", feature = "stream_cipher"))]
pub mod shared_key;
pub mod symmetric;
+5 -9
View File
@@ -1,23 +1,19 @@
[package]
name = "nym-dkg"
version.workspace = true
version = "0.1.0"
edition = "2021"
resolver = "2"
license.workspace = true
description = "Nym's Distributed Key Generation functionality"
repository.workspace = true
homepage.workspace = true
documentation.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
bitvec = { workspace = true }
# unfortunately until https://github.com/zkcrypto/nym-bls12_381-fork/issues/10 is resolved, we have to rely on the fork
# unfortunately until https://github.com/zkcrypto/bls12_381/issues/10 is resolved, we have to rely on the fork
# as we need to be able to serialize Gt so that we could create the lookup table for baby-step-giant-step algorithm
nym-bls12_381-fork = { workspace = true, features = ["alloc", "pairings", "experimental", "zeroize"] }
nym-contracts-common = { workspace = true, optional = true }
bls12_381 = { workspace = true, default-features = false, features = ["alloc", "pairings", "experimental", "zeroize"] }
nym-contracts-common = { path = "../cosmwasm-smart-contracts/contracts-common", optional = true }
bs58 = { workspace = true }
@@ -30,7 +26,7 @@ serde_derive = { workspace = true }
thiserror = { workspace = true }
zeroize = { workspace = true, features = ["zeroize_derive"] }
nym-pemstore = { workspace = true }
nym-pemstore = { path = "../pemstore" }
[dependencies.group]
workspace = true
+1 -1
View File
@@ -1,9 +1,9 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use bls12_381::{G1Projective, G2Affine, G2Prepared, Scalar};
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use ff::Field;
use nym_bls12_381_fork::{G1Projective, G2Affine, G2Prepared, Scalar};
use nym_dkg::bte::encryption::BabyStepGiantStepLookup;
use nym_dkg::bte::proof_chunking::ProofOfChunking;
use nym_dkg::bte::proof_discrete_log::ProofOfDiscreteLog;

Some files were not shown because too many files have changed in this diff Show More