diff --git a/.env.example b/.env.example index 5de7122..c4fd7d0 100644 --- a/.env.example +++ b/.env.example @@ -92,6 +92,75 @@ # Default: not set # RISC0_DEV_MODE=1 +# ============================================================ +# SP1 ZK Backend Settings +# ============================================================ + +# SP1 Prover Mode +# Options: cpu, network, cuda, mock +# - cpu: Local CPU proving (slow, high memory usage, requires Docker for Groth16) +# - network: Succinct Prover Network (fast, requires API key) +# - cuda: Local CUDA GPU proving (fastest, requires NVIDIA GPU) +# - mock: Mock proving for testing (instant, no real proofs) +# Default: cpu +# SP1_PROVER=network + +# SP1 Proof Type +# Options: compressed, groth16, plonk +# - compressed: Compressed STARK (~4-5MB, off-chain verification) +# - groth16: Groth16 SNARK (~260 bytes, on-chain, Sui compatible) +# - plonk: PLONK SNARK (~868 bytes, on-chain, no trusted setup) +# Default: compressed +# SP1_PROOF_MODE=groth16 + +# Network Prover Configuration (required for SP1_PROVER=network) +# Get your API key from: https://network.succinct.xyz +# +# SECURITY WARNING: Never commit private keys to version control! +# RECOMMENDED: Use `export NETWORK_PRIVATE_KEY=0x...` in your shell instead of storing in .env +# NETWORK_PRIVATE_KEY=0x... + +# Custom RPC endpoint (optional, defaults to mainnet) +# NETWORK_RPC_URL=https://rpc.succinct.xyz + +# ============================================================ +# Sui Blockchain Integration +# ============================================================ + +# Sui network to connect to +# Options: mainnet, testnet, local +# Default: testnet +# SUI_NETWORK=testnet + +# Deployed game package ID (Move package object ID) +# Required for blockchain interactions +# Get this after deploying contracts with `sui client publish` +# SUI_PACKAGE_ID=0x... + +# Verifying key object ID (on-chain VK for proof verification) +# Automatically set after running `just sui-setup` +# SUI_VK_OBJECT_ID=0x... + +# Game session object ID (for current active session) +# Set when creating a new on-chain session +# SUI_SESSION_OBJECT_ID=0x... + +# Custom RPC endpoint URL (optional, overrides network default) +# Defaults: +# mainnet: https://fullnode.mainnet.sui.io:443 +# testnet: https://fullnode.testnet.sui.io:443 +# local: http://127.0.0.1:9000 +# SUI_RPC_URL=https://custom-rpc.example.com + +# Gas budget for transactions (in MIST) +# Default: 100000000 (0.1 SUI) +# SUI_GAS_BUDGET=100000000 + +# Active address alias (for sui keystore) +# Used to select which address to use for transactions +# Default: first address in keystore +# SUI_ACTIVE_ALIAS=my_address_alias + # ============================================================ # Advanced: Runtime Tuning # ============================================================ diff --git a/CLAUDE.md b/CLAUDE.md index 113fb86..ae75e83 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -15,7 +15,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ### Technical Architecture -**Multi-Backend ZK System**: Supports RISC0 zkVM (production) and stub prover (testing), with planned SP1/Arkworks support +**Multi-Backend ZK System**: Supports RISC0 zkVM (production), SP1 zkVM (production), and stub prover (testing), with planned Arkworks support **Three-Layer Design**: 1. **game-core**: Pure state machine with 3-phase action pipeline (pre_validate → apply → post_validate) @@ -59,6 +59,10 @@ just run-fast stub just build risc0 just run risc0 +# SP1 backend (alternative production backend, all platforms) +just build sp1 +just run sp1 + # Set default backend via environment variable export ZK_BACKEND=stub just build # automatically uses stub @@ -73,7 +77,8 @@ just help ### Common Just Commands - `just build [backend]` - Build workspace with specified backend -- `just run [backend]` - Run CLI client +- `just run [backend]` - Run CLI client (no blockchain) +- `just run-sui [backend]` - Run CLI client with Sui blockchain integration - `just run-fast [backend]` - Run in fast mode (no proof generation, no persistence) - `just test [backend]` - Run all tests - `just lint [backend]` - Run clippy lints @@ -85,11 +90,19 @@ just help - `just tail-logs [session]` - Monitor client logs in real-time - `just clean-data` - Clean save data and logs (with confirmation) +#### Sui Blockchain Commands + +- `just sui-keygen [alias] [scheme]` - Generate a new Sui address and private key +- `just sui-deploy [network]` - Deploy Sui Move contracts to a network +- `just sui-setup [network]` - Setup deployment (register VK, etc.) +- `just sui-info [network]` - Show deployment info for a network +- `just sui-clean [network]` - Clean deployment info for a network + ### Available ZK Backends -- `risc0` - RISC0 zkVM (production, real proofs, slow guest compilation) +- `risc0` - RISC0 zkVM (production, real proofs, Linux x86_64 only for Groth16) +- `sp1` - SP1 zkVM (production, real proofs, all platforms including macOS) - `stub` - Stub prover (instant, no real proofs, testing only) -- `sp1` - SP1 zkVM (not implemented yet) - `arkworks` - Arkworks circuits (not implemented yet) ### Direct Cargo Commands (without Just) @@ -97,26 +110,44 @@ just help If you prefer not to use Just, you can use cargo directly: ```bash -# Stub backend (fast development) -cargo build --workspace --no-default-features --features stub -cargo run -p client-cli --no-default-features --features stub -cargo test --workspace --no-default-features --features stub +# CLI only (no blockchain) +cargo run -p dungeon-client --no-default-features --features "cli,stub" + +# CLI + Sui blockchain +cargo run -p dungeon-client --no-default-features --features "cli,sui,sp1" -# RISC0 backend (default) -cargo build --workspace -RISC0_SKIP_BUILD=1 cargo build --workspace # skip guest builds +# Test workspace +cargo test --workspace --no-default-features --features stub # Lint and format -cargo lint # uses default backend (risc0) +cargo clippy --workspace --all-targets --no-default-features --features stub cargo fmt --all ``` ### Environment Variables -- `ZK_BACKEND` - Set default backend for Just commands (risc0, risc0-fast, stub, sp1, arkworks) +#### General Configuration +- `ZK_BACKEND` - Set default backend for Just commands (risc0, stub, sp1, arkworks) +- `RUST_LOG=info` - Logging level (use `info` or `warn` only - `debug` causes RISC0 to pollute TUI output) +- `ENABLE_ZK_PROVING=false` - Disable proof generation entirely (fast mode) +- `ENABLE_PERSISTENCE=false` - Disable state/action persistence (fast mode) + +#### RISC0 Specific - `RISC0_SKIP_BUILD=1` - Skip guest builds during cargo build (use for fast iteration) - `RISC0_DEV_MODE=1` - Fast dev proofs (when running with real RISC0 backend) -- `RUST_LOG=info` - Logging level (use `info` or `warn` only - `debug` causes RISC0 to pollute TUI output) + +#### SP1 Specific +- `SP1_PROVER` - SP1 prover mode (cpu, network, cuda, mock) + - `cpu` (default): Local CPU proving (slow, high memory) + - `network`: Succinct Prover Network (fast, requires API key) + - `cuda`: Local CUDA GPU proving (fastest, requires NVIDIA GPU) + - `mock`: Mock proving for testing (instant, no real proofs) +- `SP1_PROOF_MODE` - SP1 proof type (compressed, groth16, plonk) + - `compressed` (default): Compressed STARK (~4-5MB, off-chain) + - `groth16`: Groth16 SNARK (~260 bytes, on-chain, Sui compatible) + - `plonk`: PLONK SNARK (~868 bytes, on-chain, no trusted setup) +- `NETWORK_PRIVATE_KEY` - Private key for SP1 Prover Network (required for network mode) +- `NETWORK_RPC_URL` - Custom RPC endpoint for SP1 Prover Network (optional, defaults to mainnet) ## Architecture @@ -129,15 +160,96 @@ crates/ │ └── content/ # Static content and fixtures exposed through oracle adapters ├── runtime/ # Public API (RuntimeHandle), orchestrator, workers, oracles, repositories ├── zk/ # Proving utilities reused by prover worker and off-chain services -├── client/ -│ ├── core/ # Cross-frontend primitives: event handling, message logging, view models (crate: client-core) -│ ├── bootstrap/ # Bootstrap utilities: configuration, oracle factories, runtime setup (crate: client-bootstrap) -│ └── cli/ # Async terminal application with cursor system and examine UI (crate: client-cli) +├── client/ # Composable binary (dungeon-client) +│ ├── bootstrap/ # Runtime initialization (proving, persistence, oracles) +│ ├── frontend/ +│ │ ├── core/ # UI primitives (events, messages, view models) - client-frontend-core +│ │ └── cli/ # Terminal UI library - client-frontend-cli +│ └── blockchain/ +│ ├── core/ # Blockchain abstraction (traits) - client-blockchain-core +│ └── sui/ # Sui implementation - client-blockchain-sui └── xtask/ # Development tools (cargo xtask pattern): tail-logs, clean-data ``` **Dependency flow**: `client`, `runtime`, `zk` → depend on `game/core` only. Never the reverse. +### zk: Zero-Knowledge Proof Backends + +The `crates/zk` crate provides a unified interface for multiple zkVM backends with feature-gated compilation: + +**Backend Architecture:** +- **RISC0 zkVM** (`feature = "risc0"`): Production-ready zkVM with mature tooling + - Guest program: `methods/risc0/state-transition/` (RISC0-specific APIs) + - Groth16 compression: Linux x86_64 only, ~200 bytes + - Requires: Docker for Groth16, RISC0 toolchain + - Status: ✅ Fully implemented and tested + +- **SP1 zkVM** (`feature = "sp1"`): Alternative production zkVM with cross-platform support + - Guest program: `methods/sp1/state-transition/` (SP1-specific APIs) + - Groth16 compression: All platforms (macOS, Linux, Windows), ~260 bytes + - PLONK compression: All platforms, ~868 bytes, no trusted setup required + - Requires: SP1 toolchain (`sp1up`) + - Status: ✅ Fully implemented, identical logic to RISC0 + +- **Stub Prover** (`feature = "stub"`): Testing-only backend for fast iteration + - No real proofs generated (instant execution) + - Same interface as production backends + - Status: ✅ Used for development + +**Proof Structure (Identical Across Backends):** +Both RISC0 and SP1 use the same 168-byte public values structure: +```text +1. oracle_root (32 bytes) - Commitment to static game content +2. seed_commitment (32 bytes) - Commitment to RNG seed +3. prev_state_root (32 bytes) - State hash before execution +4. actions_root (32 bytes) - Commitment to action sequence +5. new_state_root (32 bytes) - State hash after execution +6. new_nonce (8 bytes) - Action counter after execution +Total: 168 bytes +``` + +**Two-Stage Verification Model:** +- **Stage 1 (On-chain):** Groth16/PLONK proof verification with SHA-256 digest +- **Stage 2 (On-chain):** Public values content extraction and validation + +**Guest Program Design:** +- Core execution logic is identical between RISC0 and SP1 +- Only I/O APIs differ (`risc0_zkvm::guest::env` vs `sp1_zkvm::io`) +- Separate directories for clear separation: `methods/risc0/` and `methods/sp1/` +- Both use `commit_slice()` pattern to avoid serialization overhead +- Optimizations: Delta tracking disabled in zkVM mode (via `zkvm` feature flag) + +**Backend Selection:** +```rust +// Feature flags in Cargo.toml (mutually exclusive) +[features] +default = ["risc0"] +risc0 = ["zkvm", "dep:risc0-zkvm", ...] +sp1 = ["zkvm", "dep:sp1-sdk", ...] +stub = ["zkvm"] +``` + +**Host-Side Prover Interface:** +```rust +pub trait Prover { + fn prove(&self, start: &GameState, actions: &[Action], end: &GameState) -> Result; + fn verify(&self, proof: &ProofData) -> Result; +} + +// Unified proof data structure +pub struct ProofData { + bytes: Vec, // Serialized proof + backend: ProofBackend, // Risc0, Sp1, or Stub + journal: Vec, // 168-byte public values + journal_digest: [u8; 32], // SHA-256(journal) +} +``` + +**When to Choose Which Backend:** +- **RISC0**: Mature ecosystem, extensive documentation, proven in production +- **SP1**: Cross-platform Groth16/PLONK, faster iteration on macOS, PLONK trustless setup +- **Stub**: Development and testing only (instant, no real proofs) + ### game/core: Pure State Machine - **Responsibility**: Deterministic rules engine, domain models, state management, and pure action execution @@ -187,9 +299,9 @@ crates/ - **Hook System**: Post-execution hooks with priority ordering, chaining support, and criticality levels (Critical, Important, Optional) - **AI System**: 3-layer utility-based AI (Intent → Tactic → Action) using TraitProfile composition (Species × Archetype × Faction × Temperament) -### client/core: Cross-Frontend Primitives +### client/frontend/core: Cross-Frontend Primitives -- **Crate name**: `client-core` (located at `crates/client/core/`) +- **Crate name**: `client-frontend-core` (located at `crates/client/frontend/core/`) - **Responsibility**: Shared UX glue for presenting the game across different frontend implementations - **Modules**: - `event`: Event handling and consumption (`EventConsumer`, `EventImpact`) @@ -197,8 +309,9 @@ crates/ - `message`: Message logging and formatting - `targeting`: Targeting system for tactical interactions - `view_model`: View models for rendering game state + - `config`: Frontend configuration (`FrontendConfig` with channel and message settings) - **Purpose**: Reusable presentation logic shared across CLI, GUI, and other frontend crates -- **Exports**: `EventConsumer`, `EventImpact`, frontend abstractions, view models +- **Exports**: `EventConsumer`, `EventImpact`, `FrontendConfig`, frontend abstractions, view models ### client/bootstrap: Runtime Setup & Configuration @@ -211,17 +324,122 @@ crates/ - **Purpose**: Reusable setup code shared across CLI, UI, and other front-end crates - **Exports**: `RuntimeBuilder`, `RuntimeSetup`, `CliConfig`, `OracleBundle`, `OracleFactory`, `ContentOracleFactory` -### client/cli: Terminal Interface +### client/frontend/cli: Terminal Interface -- **Crate name**: `client-cli` (located at `crates/client/cli/`) +- **Crate name**: `client-frontend-cli` (located at `crates/client/frontend/cli/`) - **Responsibility**: Async terminal application with cursor system, examine UI, and tactical interactions -- **Architecture**: Consumes `client-core` and `client-bootstrap`, subscribes to runtime events, renders state +- **Architecture**: Consumes `client-frontend-core` and `client-bootstrap`, subscribes to runtime events, renders state - **Modules**: - - `app`: Main application loop and state management + - `app`: Main application loop and state management (`CliApp`, `CliAppBuilder`) + - `config`: CLI-specific configuration (`CliConfig`) - `cursor`: Cursor system for examine mode and targeting - `input`: User input handling and command parsing - `presentation`: Terminal rendering and UI components + - `logging`: Platform-specific log directory setup - **Interaction**: Collects player commands, validates entity/turn alignment, forwards actions to runtime +- **Exports**: `CliApp`, `CliAppBuilder`, `CliConfig`, `FrontendConfig`, `RuntimeConfig`, `setup_logging` + +### client/blockchain: Blockchain Integration Layer + +The blockchain subsystem provides a pluggable abstraction for submitting ZK proofs to various blockchain networks. It follows the same trait-based pattern as the `zk` crate, allowing multiple blockchain implementations behind a common interface. + +#### client/blockchain/core: Blockchain Abstraction + +- **Crate name**: `client-blockchain-core` (located at `crates/client/blockchain/core/`) +- **Responsibility**: Trait definitions and types for blockchain-agnostic proof submission +- **Architecture**: Trait-based abstraction similar to `zk::Prover` pattern +- **Core Modules**: + - `traits`: Blockchain client trait definitions + - `types`: Common blockchain types (session, transaction, proof metadata) + - `mock`: Mock implementation for testing +- **Trait Hierarchy**: + ```rust + // Core trait composition + pub trait BlockchainClient: ProofSubmitter + SessionManager + Send + Sync { + async fn list_pending_proofs(&self) -> Result>; + async fn submit_all_pending(&self, session_id: &SessionId) -> Result>; + fn config(&self) -> &dyn BlockchainConfig; + async fn health_check(&self) -> Result<()>; + } + + // Proof submission operations + pub trait ProofSubmitter { + async fn submit_proof(&self, session_id: &SessionId, proof_data: ProofData) -> Result; + async fn query_transaction(&self, tx_id: &TransactionId) -> Result; + } + + // Session lifecycle management + pub trait SessionManager { + async fn create_session(&self, initial_state_root: [u8; 32]) -> Result; + async fn get_session_state(&self, session_id: &SessionId) -> Result; + async fn finalize_session(&self, session_id: &SessionId) -> Result; + } + + // Blockchain-specific configuration + pub trait BlockchainConfig { + fn network_name(&self) -> &str; + fn rpc_url(&self) -> &str; + fn validate(&self) -> Result<(), String>; + } + ``` +- **Common Types**: + - `SessionId`: Opaque session identifier + - `TransactionId`: Blockchain transaction hash/ID + - `TransactionStatus`: Pending, Confirmed, or Failed + - `ProofMetadata`: Proof tracking info (session, nonce, timestamp) + - `SubmissionResult`: Transaction result with ID and status +- **Design Principles**: + - Blockchain-agnostic abstractions (no Sui/Ethereum-specific types) + - Async-first API using `#[async_trait]` + - Explicit session management for multi-proof workflows + - Network-based errors with context preservation + +#### client/blockchain/sui: Sui Implementation + +- **Crate name**: `client-blockchain-sui` (located at `crates/client/blockchain/sui/`) +- **Responsibility**: Sui-specific blockchain client implementation +- **Architecture**: Implements `BlockchainClient` trait using Sui SDK +- **Core Modules**: + - `client`: `SuiBlockchainClient` implementation + - `config`: Sui network configuration (`SuiConfig`, `SuiNetwork`) + - `converter`: Proof format conversion for Sui Move contracts + - `session`: Session state management and transaction building +- **Sui Networks**: + - `Mainnet`: Production Sui network (`https://fullnode.mainnet.sui.io:443`) + - `Testnet`: Testing network (`https://fullnode.testnet.sui.io:443`) + - `Local`: Local development network (`http://127.0.0.1:9000`) +- **Configuration**: + ```rust + pub struct SuiConfig { + pub network: SuiNetwork, + pub rpc_url: Option, // Custom RPC override + pub package_id: Option, // Deployed game contract + pub gas_budget: u64, // Transaction gas budget (MIST) + } + + // Environment variable loading + SUI_NETWORK=testnet # Network selection (default: testnet) + SUI_RPC_URL= # Custom RPC endpoint + SUI_PACKAGE_ID=0x... # Game package ID + SUI_GAS_BUDGET=100000000 # Gas budget in MIST (default: 0.1 SUI) + ``` +- **Proof Submission Flow**: + 1. Convert `ProofData` to Sui format via `SuiProofConverter` + 2. Build Move transaction calling verification contract + 3. Estimate gas and submit transaction + 4. Track transaction status until confirmation +- **Session Management**: + - Sessions map to on-chain game state objects + - Session creation initializes state with `initial_state_root` + - Proof submissions update session state progressively + - Session finalization locks the session and returns final transaction +- **Status**: Placeholder implementation (Sui SDK integration pending) + +#### Future Blockchain Implementations + +- **Ethereum**: Planned support for EVM-based chains (Ethereum, Polygon, etc.) +- **Feature Flags**: Each blockchain backend is feature-gated for optional compilation +- **Composability**: Frontends can be built with or without blockchain integration ## Code Organization Patterns diff --git a/Cargo.lock b/Cargo.lock index 21187f7..7ee0277 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,3716 +3,14829 @@ version = 4 [[package]] -name = "ahash" -version = "0.8.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - -[[package]] -name = "aho-corasick" -version = "1.1.3" +name = "Inflector" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" dependencies = [ - "memchr", + "lazy_static", + "regex", ] [[package]] -name = "allocator-api2" -version = "0.2.21" +name = "accesskit" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" +checksum = "d3d3b8f9bae46a948369bc4a03e815d4ed6d616bd00de4051133a5019dc31c5a" [[package]] -name = "android_system_properties" -version = "0.1.5" +name = "accesskit_consumer" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +checksum = "f47983a1084940ba9a39c077a8c63e55c619388be5476ac04c804cfbd1e63459" dependencies = [ - "libc", + "accesskit", + "hashbrown 0.15.5", + "immutable-chunkmap", ] [[package]] -name = "anstream" -version = "0.6.21" +name = "accesskit_macos" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +checksum = "7329821f3bd1101e03a7d2e03bd339e3ac0dc64c70b4c9f9ae1949e3ba8dece1" dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is_terminal_polyfill", - "utf8parse", + "accesskit", + "accesskit_consumer", + "hashbrown 0.15.5", + "objc2 0.5.2", + "objc2-app-kit", + "objc2-foundation", ] [[package]] -name = "anstyle" -version = "1.0.13" +name = "accesskit_windows" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" +checksum = "24fcd5d23d70670992b823e735e859374d694a3d12bfd8dd32bd3bd8bedb5d81" +dependencies = [ + "accesskit", + "accesskit_consumer", + "hashbrown 0.15.5", + "paste", + "static_assertions", + "windows 0.58.0", + "windows-core 0.58.0", +] [[package]] -name = "anstyle-parse" -version = "0.2.7" +name = "accesskit_winit" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +checksum = "6a6a48dad5530b6deb9fc7a52cc6c3bf72cdd9eb8157ac9d32d69f2427a5e879" dependencies = [ - "utf8parse", + "accesskit", + "accesskit_macos", + "accesskit_windows", + "raw-window-handle", + "winit", ] [[package]] -name = "anstyle-query" -version = "1.1.4" +name = "addchain" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" +checksum = "3b2e69442aa5628ea6951fa33e24efe8313f4321a91bd729fc2f75bdfc858570" dependencies = [ - "windows-sys 0.60.2", + "num-bigint 0.3.3", + "num-integer", + "num-traits", ] [[package]] -name = "anstyle-wincon" -version = "3.0.10" +name = "addr2line" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" +checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" dependencies = [ - "anstyle", - "once_cell_polyfill", - "windows-sys 0.60.2", + "gimli", ] [[package]] -name = "anyhow" -version = "1.0.100" +name = "adler2" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] -name = "ark-bn254" -version = "0.5.0" +name = "aead" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d69eab57e8d2663efa5c63135b2af4f396d66424f88954c21104125ab6b3e6bc" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" dependencies = [ - "ark-ec", - "ark-ff", - "ark-r1cs-std", - "ark-std", + "crypto-common", + "generic-array 0.14.7", ] [[package]] -name = "ark-crypto-primitives" -version = "0.5.0" +name = "aes" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e0c292754729c8a190e50414fd1a37093c786c709899f29c9f7daccecfa855e" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ - "ahash", - "ark-crypto-primitives-macros", - "ark-ec", - "ark-ff", - "ark-relations", - "ark-serialize", - "ark-snark", - "ark-std", - "blake2", - "derivative", - "digest", - "fnv", - "merlin", - "sha2", + "cfg-if", + "cipher", + "cpufeatures", ] [[package]] -name = "ark-crypto-primitives-macros" -version = "0.5.0" +name = "aes-gcm" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7e89fe77d1f0f4fe5b96dfc940923d88d17b6a773808124f21e764dfb063c6a" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.108", + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle", ] [[package]] -name = "ark-ec" -version = "0.5.0" +name = "aes-gcm-siv" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d68f2d516162846c1238e755a7c4d131b892b70cc70c471a8e3ca3ed818fce" +checksum = "ae0784134ba9375416d469ec31e7c5f9fa94405049cf08c5ce5b4698be673e0d" dependencies = [ - "ahash", - "ark-ff", - "ark-poly", - "ark-serialize", - "ark-std", - "educe", - "fnv", - "hashbrown 0.15.5", - "itertools 0.13.0", - "num-bigint", - "num-integer", - "num-traits", + "aead", + "aes", + "cipher", + "ctr", + "polyval", + "subtle", "zeroize", ] [[package]] -name = "ark-ff" -version = "0.5.0" +name = "ahash" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a177aba0ed1e0fbb62aa9f6d0502e9b46dad8c2eab04c14258a1212d2557ea70" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ - "ark-ff-asm", - "ark-ff-macros", - "ark-serialize", - "ark-std", - "arrayvec", - "digest", - "educe", - "itertools 0.13.0", - "num-bigint", - "num-traits", - "paste", - "zeroize", + "cfg-if", + "const-random", + "getrandom 0.3.4", + "once_cell", + "version_check", + "zerocopy", ] [[package]] -name = "ark-ff-asm" -version = "0.5.0" +name = "aho-corasick" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ - "quote", - "syn 2.0.108", + "memchr", ] [[package]] -name = "ark-ff-macros" -version = "0.5.0" +name = "aliasable" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09be120733ee33f7693ceaa202ca41accd5653b779563608f1234f78ae07c4b3" -dependencies = [ - "num-bigint", - "num-traits", - "proc-macro2", - "quote", - "syn 2.0.108", -] +checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" [[package]] -name = "ark-groth16" -version = "0.5.0" +name = "alloc-no-stdlib" +version = "2.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88f1d0f3a534bb54188b8dcc104307db6c56cdae574ddc3212aec0625740fc7e" -dependencies = [ - "ark-crypto-primitives", - "ark-ec", - "ark-ff", - "ark-poly", - "ark-relations", - "ark-serialize", - "ark-std", -] +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" [[package]] -name = "ark-poly" -version = "0.5.0" +name = "alloc-stdlib" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "579305839da207f02b89cd1679e50e67b4331e2f9294a57693e5051b7703fe27" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" dependencies = [ - "ahash", - "ark-ff", - "ark-serialize", - "ark-std", - "educe", - "fnv", - "hashbrown 0.15.5", + "alloc-no-stdlib", ] [[package]] -name = "ark-r1cs-std" -version = "0.5.0" +name = "allocative" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "941551ef1df4c7a401de7068758db6503598e6f01850bdb2cfdb614a1f9dbea1" +checksum = "8fac2ce611db8b8cee9b2aa886ca03c924e9da5e5295d0dbd0526e5d0b0710f7" dependencies = [ - "ark-ec", - "ark-ff", - "ark-relations", - "ark-std", - "educe", - "num-bigint", - "num-integer", - "num-traits", - "tracing", + "allocative_derive", + "bumpalo", + "ctor", + "hashbrown 0.14.5", + "num-bigint 0.4.6", ] [[package]] -name = "ark-relations" -version = "0.5.1" +name = "allocative_derive" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec46ddc93e7af44bcab5230937635b06fb5744464dd6a7e7b083e80ebd274384" +checksum = "fe233a377643e0fc1a56421d7c90acdec45c291b30345eb9f08e8d0ddce5a4ab" dependencies = [ - "ark-ff", - "ark-std", - "tracing", - "tracing-subscriber 0.2.25", + "proc-macro2", + "quote", + "syn 2.0.110", ] [[package]] -name = "ark-serialize" -version = "0.5.0" +name = "allocator-api2" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f4d068aaf107ebcd7dfb52bc748f8030e0fc930ac8e360146ca54c1203088f7" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "alloy-consensus" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6440213a22df93a87ed512d2f668e7dc1d62a05642d107f82d61edc9e12370" dependencies = [ - "ark-serialize-derive", - "ark-std", - "arrayvec", - "digest", - "num-bigint", + "alloy-eips", + "alloy-primitives", + "alloy-rlp", + "alloy-serde", + "alloy-trie", + "alloy-tx-macros", + "auto_impl", + "borsh", + "c-kzg", + "derive_more 2.0.1", + "either", + "k256 0.13.4", + "once_cell", + "rand 0.8.5", + "secp256k1 0.30.0", + "serde", + "serde_json", + "serde_with", + "thiserror 2.0.17", ] [[package]] -name = "ark-serialize-derive" -version = "0.5.0" +name = "alloy-consensus-any" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213888f660fddcca0d257e88e54ac05bca01885f258ccdf695bafd77031bb69d" +checksum = "15d0bea09287942405c4f9d2a4f22d1e07611c2dbd9d5bf94b75366340f9e6e0" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.108", + "alloy-consensus", + "alloy-eips", + "alloy-primitives", + "alloy-rlp", + "alloy-serde", + "serde", ] [[package]] -name = "ark-snark" -version = "0.5.1" +name = "alloy-eip2124" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d368e2848c2d4c129ce7679a7d0d2d612b6a274d3ea6a13bad4445d61b381b88" +checksum = "741bdd7499908b3aa0b159bba11e71c8cddd009a2c2eb7a06e825f1ec87900a5" dependencies = [ - "ark-ff", - "ark-relations", - "ark-serialize", - "ark-std", + "alloy-primitives", + "alloy-rlp", + "crc", + "serde", + "thiserror 2.0.17", ] [[package]] -name = "ark-std" -version = "0.5.0" +name = "alloy-eip2930" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "246a225cc6131e9ee4f24619af0f19d67761fff15d7ccc22e42b80846e69449a" +checksum = "9441120fa82df73e8959ae0e4ab8ade03de2aaae61be313fbf5746277847ce25" dependencies = [ - "num-traits", - "rand 0.8.5", + "alloy-primitives", + "alloy-rlp", + "borsh", + "serde", ] [[package]] -name = "arraydeque" -version = "0.5.1" +name = "alloy-eip7702" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236" +checksum = "2919c5a56a1007492da313e7a3b6d45ef5edc5d33416fdec63c0d7a2702a0d20" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "borsh", + "serde", + "thiserror 2.0.17", +] [[package]] -name = "arrayvec" -version = "0.7.6" +name = "alloy-eips" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +checksum = "4bd2c7ae05abcab4483ce821f12f285e01c0b33804e6883dd9ca1569a87ee2be" dependencies = [ + "alloy-eip2124", + "alloy-eip2930", + "alloy-eip7702", + "alloy-primitives", + "alloy-rlp", + "alloy-serde", + "auto_impl", + "borsh", + "c-kzg", + "derive_more 2.0.1", + "either", "serde", + "serde_with", + "sha2 0.10.9", + "thiserror 2.0.17", ] [[package]] -name = "async-trait" -version = "0.1.89" +name = "alloy-json-abi" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +checksum = "5513d5e6bd1cba6bdcf5373470f559f320c05c8c59493b6e98912fbe6733943f" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.108", + "alloy-primitives", + "alloy-sol-type-parser", + "serde", + "serde_json", ] [[package]] -name = "atomic-waker" +name = "alloy-json-rpc" version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" +checksum = "003f46c54f22854a32b9cc7972660a476968008ad505427eabab49225309ec40" +dependencies = [ + "alloy-primitives", + "alloy-sol-types", + "http 1.3.1", + "serde", + "serde_json", + "thiserror 2.0.17", + "tracing", +] [[package]] -name = "autocfg" -version = "1.5.0" +name = "alloy-network" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "4f4029954d9406a40979f3a3b46950928a0fdcfe3ea8a9b0c17490d57e8aa0e3" +dependencies = [ + "alloy-consensus", + "alloy-consensus-any", + "alloy-eips", + "alloy-json-rpc", + "alloy-network-primitives", + "alloy-primitives", + "alloy-rpc-types-any", + "alloy-rpc-types-eth", + "alloy-serde", + "alloy-signer", + "alloy-sol-types", + "async-trait", + "auto_impl", + "derive_more 2.0.1", + "futures-utils-wasm", + "serde", + "serde_json", + "thiserror 2.0.17", +] [[package]] -name = "base64" -version = "0.22.1" +name = "alloy-network-primitives" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +checksum = "7805124ad69e57bbae7731c9c344571700b2a18d351bda9e0eba521c991d1bcb" +dependencies = [ + "alloy-consensus", + "alloy-eips", + "alloy-primitives", + "alloy-serde", + "serde", +] [[package]] -name = "base64ct" -version = "1.8.0" +name = "alloy-primitives" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" - +checksum = "355bf68a433e0fd7f7d33d5a9fc2583fde70bf5c530f63b80845f8da5505cf28" +dependencies = [ + "alloy-rlp", + "bytes", + "cfg-if", + "const-hex", + "derive_more 2.0.1", + "foldhash 0.2.0", + "hashbrown 0.16.1", + "indexmap 2.12.1", + "itoa", + "k256 0.13.4", + "keccak-asm", + "paste", + "proptest", + "rand 0.9.2", + "ruint", + "rustc-hash 2.1.1", + "serde", + "sha3", + "tiny-keccak", +] + [[package]] -name = "behavior-tree" -version = "0.1.0" +name = "alloy-rlp" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f70d83b765fdc080dbcd4f4db70d8d23fe4761f2f02ebfa9146b833900634b4" +dependencies = [ + "alloy-rlp-derive", + "arrayvec", + "bytes", +] [[package]] -name = "bincode" -version = "1.3.3" +name = "alloy-rlp-derive" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +checksum = "64b728d511962dda67c1bc7ea7c03736ec275ed2cf4c35d9585298ac9ccf3b73" dependencies = [ - "serde", + "proc-macro2", + "quote", + "syn 2.0.110", ] [[package]] -name = "bit-vec" -version = "0.8.0" +name = "alloy-rpc-types-any" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" +checksum = "b43c1622aac2508d528743fd4cfdac1dea92d5a8fa894038488ff7edd0af0b32" +dependencies = [ + "alloy-consensus-any", + "alloy-rpc-types-eth", + "alloy-serde", +] [[package]] -name = "bitflags" -version = "1.3.2" +name = "alloy-rpc-types-eth" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +checksum = "ed5fafb741c19b3cca4cdd04fa215c89413491f9695a3e928dee2ae5657f607e" +dependencies = [ + "alloy-consensus", + "alloy-consensus-any", + "alloy-eips", + "alloy-network-primitives", + "alloy-primitives", + "alloy-rlp", + "alloy-serde", + "alloy-sol-types", + "itertools 0.14.0", + "serde", + "serde_json", + "serde_with", + "thiserror 2.0.17", +] [[package]] -name = "bitflags" -version = "2.10.0" +name = "alloy-serde" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" +checksum = "a6f180c399ca7c1e2fe17ea58343910cad0090878a696ff5a50241aee12fc529" dependencies = [ - "serde_core", + "alloy-primitives", + "serde", + "serde_json", ] [[package]] -name = "blake2" -version = "0.10.6" +name = "alloy-signer" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +checksum = "ecc39ad2c0a3d2da8891f4081565780703a593f090f768f884049aa3aa929cbc" dependencies = [ - "digest", + "alloy-primitives", + "async-trait", + "auto_impl", + "either", + "elliptic-curve 0.13.8", + "k256 0.13.4", + "thiserror 2.0.17", ] [[package]] -name = "block" -version = "0.1.6" +name = "alloy-signer-aws" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" +checksum = "75411104af460ca0b306ae998f0a00b5159457780487630f4b24722beae6b690" +dependencies = [ + "alloy-consensus", + "alloy-network", + "alloy-primitives", + "alloy-signer", + "async-trait", + "aws-config", + "aws-sdk-kms", + "k256 0.13.4", + "spki 0.7.3", + "thiserror 2.0.17", + "tracing", +] [[package]] -name = "block-buffer" -version = "0.10.4" +name = "alloy-signer-local" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +checksum = "930e17cb1e46446a193a593a3bfff8d0ecee4e510b802575ebe300ae2e43ef75" dependencies = [ - "generic-array", + "alloy-consensus", + "alloy-network", + "alloy-primitives", + "alloy-signer", + "async-trait", + "k256 0.13.4", + "rand 0.8.5", + "thiserror 2.0.17", ] [[package]] -name = "bonsai-sdk" +name = "alloy-sol-macro" version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21055e2f49cbbdbfe9f8f96d597c5527b0c6ab7933341fdc2f147180e48a988e" +checksum = "f3ce480400051b5217f19d6e9a82d9010cdde20f1ae9c00d53591e4a1afbb312" dependencies = [ - "duplicate", - "maybe-async", - "reqwest", - "serde", - "thiserror 2.0.17", + "alloy-sol-macro-expander", + "alloy-sol-macro-input", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.110", ] [[package]] -name = "borsh" -version = "1.5.7" +name = "alloy-sol-macro-expander" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad8646f98db542e39fc66e68a20b2144f6a732636df7c2354e74645faaa433ce" +checksum = "6d792e205ed3b72f795a8044c52877d2e6b6e9b1d13f431478121d8d4eaa9028" dependencies = [ - "borsh-derive", - "cfg_aliases", + "alloy-sol-macro-input", + "const-hex", + "heck 0.5.0", + "indexmap 2.12.1", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.110", + "syn-solidity", + "tiny-keccak", ] [[package]] -name = "borsh-derive" -version = "1.5.7" +name = "alloy-sol-macro-input" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdd1d3c0c2f5833f22386f252fe8ed005c7f59fdcddeef025c01b4c3b9fd9ac3" +checksum = "0bd1247a8f90b465ef3f1207627547ec16940c35597875cdc09c49d58b19693c" dependencies = [ - "once_cell", - "proc-macro-crate", + "const-hex", + "dunce", + "heck 0.5.0", + "macro-string", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", + "syn-solidity", ] [[package]] -name = "bounded-vector" -version = "0.3.2" +name = "alloy-sol-type-parser" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a4ae68aba933dbbfc135300c665cffe57d59f61bf0428c14d88a73848280776" +checksum = "954d1b2533b9b2c7959652df3076954ecb1122a28cc740aa84e7b0a49f6ac0a9" dependencies = [ "serde", - "thiserror 2.0.17", + "winnow", ] [[package]] -name = "bumpalo" -version = "3.19.0" +name = "alloy-sol-types" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +checksum = "70319350969a3af119da6fb3e9bddb1bce66c9ea933600cb297c8b1850ad2a3c" +dependencies = [ + "alloy-json-abi", + "alloy-primitives", + "alloy-sol-macro", + "serde", +] [[package]] -name = "bytemuck" -version = "1.24.0" +name = "alloy-trie" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" +checksum = "e3412d52bb97c6c6cc27ccc28d4e6e8cf605469101193b50b0bd5813b1f990b5" dependencies = [ - "bytemuck_derive", + "alloy-primitives", + "alloy-rlp", + "arrayvec", + "derive_more 2.0.1", + "nybbles", + "serde", + "smallvec", + "tracing", ] [[package]] -name = "bytemuck_derive" -version = "1.10.2" +name = "alloy-tx-macros" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" +checksum = "ae109e33814b49fc0a62f2528993aa8a2dd346c26959b151f05441dc0b9da292" dependencies = [ + "darling 0.21.3", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] -name = "byteorder" -version = "1.5.0" +name = "android-activity" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046" +dependencies = [ + "android-properties", + "bitflags 2.10.0", + "cc", + "cesu8", + "jni", + "jni-sys", + "libc", + "log", + "ndk", + "ndk-context", + "ndk-sys 0.6.0+11769913", + "num_enum 0.7.5", + "thiserror 1.0.69", +] [[package]] -name = "bytes" -version = "1.10.1" +name = "android-properties" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" -dependencies = [ - "serde", -] +checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" [[package]] -name = "camino" -version = "1.2.1" +name = "android_log-sys" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "276a59bf2b2c967788139340c9f0c5b12d7fd6630315c15c217e559de85d2609" -dependencies = [ - "serde_core", -] +checksum = "84521a3cf562bc62942e294181d9eef17eb38ceb8c68677bc49f144e4c3d4f8d" [[package]] -name = "cargo-platform" -version = "0.1.9" +name = "android_system_properties" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" dependencies = [ - "serde", + "libc", ] [[package]] -name = "cargo_metadata" -version = "0.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd5eb614ed4c27c5d706420e4320fbe3216ab31fa1c33cd8246ac36dae4479ba" +name = "anemo" +version = "0.0.0" +source = "git+https://github.com/mystenlabs/anemo.git?rev=9c52c3c7946532163a79129db15180cdb984bab4#9c52c3c7946532163a79129db15180cdb984bab4" dependencies = [ - "camino", - "cargo-platform", - "semver", + "anyhow", + "async-trait", + "bincode", + "bytes", + "ed25519", + "futures", + "hex", + "http 1.3.1", + "matchit 0.5.0", + "pin-project-lite", + "pkcs8 0.10.2", + "quinn", + "quinn-proto", + "rand 0.8.5", + "rcgen", + "ring", + "rustls 0.23.35", + "rustls-webpki 0.103.8", "serde", "serde_json", - "thiserror 2.0.17", + "socket2 0.5.10", + "tap", + "thiserror 1.0.69", + "tokio", + "tokio-util", + "tower 0.4.13", + "tracing", + "x509-parser", ] [[package]] -name = "cassowary" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" +name = "anemo-tower" +version = "0.0.0" +source = "git+https://github.com/mystenlabs/anemo.git?rev=9c52c3c7946532163a79129db15180cdb984bab4#9c52c3c7946532163a79129db15180cdb984bab4" +dependencies = [ + "anemo", + "bytes", + "dashmap", + "futures", + "governor", + "nonzero_ext", + "pin-project-lite", + "tokio", + "tower 0.4.13", + "tracing", + "uuid", +] [[package]] -name = "castaway" -version = "0.2.4" +name = "annotate-snippets" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec551ab6e7578819132c713a93c022a05d60159dc86e7a7050223577484c55a" +checksum = "ccaf7e9dfbb6ab22c82e473cd1a8a7bd313c19a5b7e40970f3d89ef5a5c9e81e" dependencies = [ - "rustversion", + "unicode-width 0.1.14", ] [[package]] -name = "cc" -version = "1.2.41" +name = "ansi_term" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac9fe6cdbb24b6ade63616c0a0688e45bb56732262c158df3c0c4bea4ca47cb7" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" dependencies = [ - "find-msvc-tools", - "shlex", + "winapi", ] [[package]] -name = "cfg-if" -version = "1.0.4" +name = "anstream" +version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] [[package]] -name = "cfg_aliases" -version = "0.2.1" +name = "anstyle" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] -name = "chrono" -version = "0.4.42" +name = "anstyle-parse" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" dependencies = [ - "iana-time-zone", - "num-traits", - "serde", - "windows-link", + "utf8parse", ] [[package]] -name = "clap" -version = "4.5.50" +name = "anstyle-query" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c2cfd7bf8a6017ddaa4e32ffe7403d547790db06bd171c1c53926faab501623" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "clap_builder", - "clap_derive", + "windows-sys 0.61.2", ] [[package]] -name = "clap_builder" -version = "4.5.50" +name = "anstyle-wincon" +version = "3.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a4c05b9e80c5ccd3a7ef080ad7b6ba7d6fc00a985b8b157197075677c82c7a0" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ - "anstream", "anstyle", - "clap_lex", - "strsim", + "once_cell_polyfill", + "windows-sys 0.61.2", ] [[package]] -name = "clap_derive" -version = "4.5.49" +name = "antithesis_sdk" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" +checksum = "dafc0460f582169b1414074fd82bedbda60456fb4df0a78dc7fef1306e732ea3" dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.108", + "libc", + "libloading", + "linkme", + "once_cell", + "rand 0.8.5", + "rustc_version_runtime", + "serde", + "serde_json", ] [[package]] -name = "clap_lex" -version = "0.7.6" +name = "anyhow" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" +dependencies = [ + "backtrace", +] [[package]] -name = "client-bootstrap" -version = "0.1.0" +name = "approx" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" dependencies = [ - "anyhow", - "game-content", - "game-core", - "runtime", - "tokio", - "tracing", -] - -[[package]] -name = "client-cli" -version = "0.1.0" -dependencies = [ - "anyhow", - "async-trait", - "client-bootstrap", - "client-core", - "crossterm 0.29.0", - "dotenvy", - "game-core", - "ratatui", - "runtime", - "thiserror 2.0.17", - "tokio", - "tracing", - "tracing-appender", - "tracing-subscriber 0.3.20", + "num-traits", ] [[package]] -name = "client-core" -version = "0.1.0" +name = "ar_archive_writer" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0c269894b6fe5e9d7ada0cf69b5bf847ff35bc25fc271f08e1d080fce80339a" dependencies = [ - "anyhow", - "arrayvec", - "async-trait", - "bitflags 2.10.0", - "game-core", - "runtime", + "object 0.32.2", ] [[package]] -name = "cobs" -version = "0.3.0" +name = "ark-bn254" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" +checksum = "a22f4561524cd949590d78d7d4c5df8f592430d221f7f3c9497bbafd8972120f" dependencies = [ - "thiserror 2.0.17", + "ark-ec 0.4.2", + "ark-ff 0.4.2", + "ark-std 0.4.0", ] [[package]] -name = "colorchoice" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" - -[[package]] -name = "compact_str" -version = "0.8.1" +name = "ark-bn254" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b79c4069c6cad78e2e0cdfcbd26275770669fb39fd308a752dc110e83b9af32" +checksum = "d69eab57e8d2663efa5c63135b2af4f396d66424f88954c21104125ab6b3e6bc" dependencies = [ - "castaway", - "cfg-if", - "itoa", - "rustversion", - "ryu", - "static_assertions", + "ark-ec 0.5.0", + "ark-ff 0.5.0", + "ark-r1cs-std", + "ark-std 0.5.0", ] [[package]] -name = "console" -version = "0.16.1" +name = "ark-crypto-primitives" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b430743a6eb14e9764d4260d4c0d8123087d504eeb9c48f2b2a5e810dd369df4" +checksum = "1f3a13b34da09176a8baba701233fdffbaa7c1b1192ce031a3da4e55ce1f1a56" dependencies = [ - "encode_unicode", - "libc", - "once_cell", - "unicode-width 0.2.0", - "windows-sys 0.61.2", + "ark-ec 0.4.2", + "ark-ff 0.4.2", + "ark-relations 0.4.0", + "ark-serialize 0.4.2", + "ark-snark 0.4.0", + "ark-std 0.4.0", + "blake2", + "derivative", + "digest 0.10.7", + "sha2 0.10.9", ] [[package]] -name = "const-oid" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" - -[[package]] -name = "convert_case" -version = "0.7.1" +name = "ark-crypto-primitives" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb402b8d4c85569410425650ce3eddc7d698ed96d39a73f941b08fb63082f1e7" +checksum = "1e0c292754729c8a190e50414fd1a37093c786c709899f29c9f7daccecfa855e" dependencies = [ - "unicode-segmentation", + "ahash", + "ark-crypto-primitives-macros", + "ark-ec 0.5.0", + "ark-ff 0.5.0", + "ark-relations 0.5.1", + "ark-serialize 0.5.0", + "ark-snark 0.5.1", + "ark-std 0.5.0", + "blake2", + "derivative", + "digest 0.10.7", + "fnv", + "merlin", + "rayon", + "sha2 0.10.9", ] [[package]] -name = "core-foundation" -version = "0.9.4" +name = "ark-crypto-primitives-macros" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +checksum = "e7e89fe77d1f0f4fe5b96dfc940923d88d17b6a773808124f21e764dfb063c6a" dependencies = [ - "core-foundation-sys", - "libc", + "proc-macro2", + "quote", + "syn 2.0.110", ] [[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "core-graphics-types" -version = "0.1.3" +name = "ark-ec" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" +checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "libc", + "ark-ff 0.4.2", + "ark-poly 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", + "derivative", + "hashbrown 0.13.2", + "itertools 0.10.5", + "num-traits", + "zeroize", ] [[package]] -name = "cpufeatures" -version = "0.2.17" +name = "ark-ec" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +checksum = "43d68f2d516162846c1238e755a7c4d131b892b70cc70c471a8e3ca3ed818fce" dependencies = [ - "libc", + "ahash", + "ark-ff 0.5.0", + "ark-poly 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", + "educe", + "fnv", + "hashbrown 0.15.5", + "itertools 0.13.0", + "num-bigint 0.4.6", + "num-integer", + "num-traits", + "rayon", + "zeroize", ] [[package]] -name = "crossbeam-channel" -version = "0.5.15" +name = "ark-ff" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +checksum = "6b3235cc41ee7a12aaaf2c575a2ad7b46713a8a50bda2fc3b003a04845c05dd6" dependencies = [ - "crossbeam-utils", + "ark-ff-asm 0.3.0", + "ark-ff-macros 0.3.0", + "ark-serialize 0.3.0", + "ark-std 0.3.0", + "derivative", + "num-bigint 0.4.6", + "num-traits", + "paste", + "rustc_version 0.3.3", + "zeroize", ] [[package]] -name = "crossbeam-utils" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" - -[[package]] -name = "crossterm" -version = "0.28.1" +name = "ark-ff" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" dependencies = [ - "bitflags 2.10.0", - "crossterm_winapi", - "mio", - "parking_lot", - "rustix 0.38.44", - "signal-hook", - "signal-hook-mio", - "winapi", + "ark-ff-asm 0.4.2", + "ark-ff-macros 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", + "derivative", + "digest 0.10.7", + "itertools 0.10.5", + "num-bigint 0.4.6", + "num-traits", + "paste", + "rustc_version 0.4.1", + "zeroize", ] [[package]] -name = "crossterm" -version = "0.29.0" +name = "ark-ff" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b" +checksum = "a177aba0ed1e0fbb62aa9f6d0502e9b46dad8c2eab04c14258a1212d2557ea70" dependencies = [ - "bitflags 2.10.0", - "crossterm_winapi", - "derive_more", - "document-features", - "futures-core", - "mio", - "parking_lot", - "rustix 1.1.2", - "signal-hook", - "signal-hook-mio", - "winapi", + "ark-ff-asm 0.5.0", + "ark-ff-macros 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", + "arrayvec", + "digest 0.10.7", + "educe", + "itertools 0.13.0", + "num-bigint 0.4.6", + "num-traits", + "paste", + "rayon", + "zeroize", ] [[package]] -name = "crossterm_winapi" -version = "0.9.1" +name = "ark-ff-asm" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +checksum = "db02d390bf6643fb404d3d22d31aee1c4bc4459600aef9113833d17e786c6e44" dependencies = [ - "winapi", + "quote", + "syn 1.0.109", ] [[package]] -name = "crypto-common" -version = "0.1.6" +name = "ark-ff-asm" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" dependencies = [ - "generic-array", - "typenum", + "quote", + "syn 1.0.109", ] [[package]] -name = "darling" -version = "0.20.11" +name = "ark-ff-asm" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60" dependencies = [ - "darling_core 0.20.11", - "darling_macro 0.20.11", + "quote", + "syn 2.0.110", ] [[package]] -name = "darling" -version = "0.21.3" +name = "ark-ff-macros" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" +checksum = "db2fd794a08ccb318058009eefdf15bcaaaaf6f8161eb3345f907222bac38b20" dependencies = [ - "darling_core 0.21.3", - "darling_macro 0.21.3", + "num-bigint 0.4.6", + "num-traits", + "quote", + "syn 1.0.109", ] [[package]] -name = "darling_core" -version = "0.20.11" +name = "ark-ff-macros" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" dependencies = [ - "fnv", - "ident_case", + "num-bigint 0.4.6", + "num-traits", "proc-macro2", "quote", - "strsim", - "syn 2.0.108", + "syn 1.0.109", ] [[package]] -name = "darling_core" -version = "0.21.3" +name = "ark-ff-macros" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" +checksum = "09be120733ee33f7693ceaa202ca41accd5653b779563608f1234f78ae07c4b3" dependencies = [ - "fnv", - "ident_case", + "num-bigint 0.4.6", + "num-traits", "proc-macro2", "quote", - "strsim", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] -name = "darling_macro" -version = "0.20.11" +name = "ark-groth16" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +checksum = "20ceafa83848c3e390f1cbf124bc3193b3e639b3f02009e0e290809a501b95fc" dependencies = [ - "darling_core 0.20.11", - "quote", - "syn 2.0.108", + "ark-crypto-primitives 0.4.0", + "ark-ec 0.4.2", + "ark-ff 0.4.2", + "ark-poly 0.4.2", + "ark-relations 0.4.0", + "ark-serialize 0.4.2", + "ark-std 0.4.0", ] [[package]] -name = "darling_macro" -version = "0.21.3" +name = "ark-groth16" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" +checksum = "88f1d0f3a534bb54188b8dcc104307db6c56cdae574ddc3212aec0625740fc7e" dependencies = [ - "darling_core 0.21.3", - "quote", - "syn 2.0.108", + "ark-crypto-primitives 0.5.0", + "ark-ec 0.5.0", + "ark-ff 0.5.0", + "ark-poly 0.5.0", + "ark-relations 0.5.1", + "ark-serialize 0.5.0", + "ark-std 0.5.0", + "rayon", ] [[package]] -name = "der" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" -dependencies = [ - "const-oid", - "pem-rfc7468", - "zeroize", -] - -[[package]] -name = "deranged" -version = "0.5.4" +name = "ark-poly" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a41953f86f8a05768a6cda24def994fd2f424b04ec5c719cf89989779f199071" +checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" dependencies = [ - "powerfmt", - "serde_core", + "ark-ff 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", + "derivative", + "hashbrown 0.13.2", ] [[package]] -name = "derivative" -version = "2.2.0" +name = "ark-poly" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +checksum = "579305839da207f02b89cd1679e50e67b4331e2f9294a57693e5051b7703fe27" dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", + "ahash", + "ark-ff 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", + "educe", + "fnv", + "hashbrown 0.15.5", + "rayon", ] [[package]] -name = "derive_builder" -version = "0.20.2" +name = "ark-r1cs-std" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947" +checksum = "941551ef1df4c7a401de7068758db6503598e6f01850bdb2cfdb614a1f9dbea1" dependencies = [ - "derive_builder_macro", + "ark-ec 0.5.0", + "ark-ff 0.5.0", + "ark-relations 0.5.1", + "ark-std 0.5.0", + "educe", + "num-bigint 0.4.6", + "num-integer", + "num-traits", + "tracing", ] [[package]] -name = "derive_builder_core" -version = "0.20.2" +name = "ark-relations" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" +checksum = "00796b6efc05a3f48225e59cb6a2cda78881e7c390872d5786aaf112f31fb4f0" dependencies = [ - "darling 0.20.11", - "proc-macro2", - "quote", - "syn 2.0.108", + "ark-ff 0.4.2", + "ark-std 0.4.0", + "tracing", ] [[package]] -name = "derive_builder_macro" -version = "0.20.2" +name = "ark-relations" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" +checksum = "ec46ddc93e7af44bcab5230937635b06fb5744464dd6a7e7b083e80ebd274384" dependencies = [ - "derive_builder_core", - "syn 2.0.108", + "ark-ff 0.5.0", + "ark-std 0.5.0", + "tracing", + "tracing-subscriber 0.2.25", ] [[package]] -name = "derive_more" -version = "2.0.1" +name = "ark-secp256k1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" +checksum = "4c02e954eaeb4ddb29613fee20840c2bbc85ca4396d53e33837e11905363c5f2" dependencies = [ - "derive_more-impl", + "ark-ec 0.4.2", + "ark-ff 0.4.2", + "ark-std 0.4.0", ] [[package]] -name = "derive_more-impl" -version = "2.0.1" +name = "ark-secp256r1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" +checksum = "3975a01b0a6e3eae0f72ec7ca8598a6620fc72fa5981f6f5cca33b7cd788f633" dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "syn 2.0.108", - "unicode-xid", + "ark-ec 0.4.2", + "ark-ff 0.4.2", + "ark-std 0.4.0", ] [[package]] -name = "digest" -version = "0.10.7" +name = "ark-serialize" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +checksum = "1d6c2b318ee6e10f8c2853e73a83adc0ccb88995aa978d8a3408d492ab2ee671" dependencies = [ - "block-buffer", - "const-oid", - "crypto-common", - "subtle", + "ark-std 0.3.0", + "digest 0.9.0", ] [[package]] -name = "directories" -version = "6.0.0" +name = "ark-serialize" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16f5094c54661b38d03bd7e50df373292118db60b585c08a411c6d840017fe7d" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" dependencies = [ - "dirs-sys", + "ark-serialize-derive 0.4.2", + "ark-std 0.4.0", + "digest 0.10.7", + "num-bigint 0.4.6", ] [[package]] -name = "dirs" -version = "6.0.0" +name = "ark-serialize" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" +checksum = "3f4d068aaf107ebcd7dfb52bc748f8030e0fc930ac8e360146ca54c1203088f7" dependencies = [ - "dirs-sys", + "ark-serialize-derive 0.5.0", + "ark-std 0.5.0", + "arrayvec", + "digest 0.10.7", + "num-bigint 0.4.6", + "rayon", ] [[package]] -name = "dirs-sys" -version = "0.5.0" +name = "ark-serialize-derive" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" +checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" dependencies = [ - "libc", - "option-ext", - "redox_users", - "windows-sys 0.61.2", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] -name = "displaydoc" -version = "0.2.5" +name = "ark-serialize-derive" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +checksum = "213888f660fddcca0d257e88e54ac05bca01885f258ccdf695bafd77031bb69d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] -name = "docker-generate" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf673e0848ef09fa4aeeba78e681cf651c0c7d35f76ee38cec8e55bc32fa111" - -[[package]] -name = "document-features" -version = "0.2.11" +name = "ark-snark" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d" +checksum = "84d3cc6833a335bb8a600241889ead68ee89a3cf8448081fb7694c0fe503da63" dependencies = [ - "litrs", + "ark-ff 0.4.2", + "ark-relations 0.4.0", + "ark-serialize 0.4.2", + "ark-std 0.4.0", ] [[package]] -name = "dotenvy" -version = "0.15.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" - -[[package]] -name = "downcast-rs" -version = "1.2.1" +name = "ark-snark" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" +checksum = "d368e2848c2d4c129ce7679a7d0d2d612b6a274d3ea6a13bad4445d61b381b88" +dependencies = [ + "ark-ff 0.5.0", + "ark-relations 0.5.1", + "ark-serialize 0.5.0", + "ark-std 0.5.0", +] [[package]] -name = "duplicate" -version = "2.0.0" +name = "ark-std" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97af9b5f014e228b33e77d75ee0e6e87960124f0f4b16337b586a6bec91867b1" +checksum = "1df2c09229cbc5a028b1d70e00fdb2acee28b1055dfb5ca73eea49c5a25c4e7c" dependencies = [ - "heck", - "proc-macro2", - "proc-macro2-diagnostics", + "num-traits", + "rand 0.8.5", ] [[package]] -name = "dyn-clone" -version = "1.0.20" +name = "ark-std" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand 0.8.5", +] [[package]] -name = "educe" -version = "0.6.0" +name = "ark-std" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7bc049e1bd8cdeb31b68bbd586a9464ecf9f3944af3958a7a9d0f8b9799417" +checksum = "246a225cc6131e9ee4f24619af0f19d67761fff15d7ccc22e42b80846e69449a" dependencies = [ - "enum-ordinalize", - "proc-macro2", - "quote", - "syn 2.0.108", + "num-traits", + "rand 0.8.5", + "rayon", ] [[package]] -name = "either" -version = "1.15.0" +name = "arraydeque" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236" [[package]] -name = "elf" -version = "0.7.4" +name = "arrayref" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4445909572dbd556c457c849c4ca58623d84b27c8fff1e74b0b4227d8b90d17b" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" [[package]] -name = "embedded-io" -version = "0.4.0" +name = "arrayvec" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +dependencies = [ + "serde", +] [[package]] -name = "embedded-io" -version = "0.6.1" +name = "as-raw-xcb-connection" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" +checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" [[package]] -name = "encode_unicode" -version = "1.0.0" +name = "ascii-canvas" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" +checksum = "8824ecca2e851cec16968d54a01dd372ef8f95b244fb84b84e70128be347c3c6" +dependencies = [ + "term", +] [[package]] -name = "encoding_rs" -version = "0.8.35" +name = "ash" +version = "0.38.0+1.3.281" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +checksum = "0bb44936d800fea8f016d7f2311c6a4f97aebd5dc86f09906139ec848cf3a46f" dependencies = [ - "cfg-if", + "libloading", ] [[package]] -name = "enum-ordinalize" -version = "4.3.0" +name = "asn1-rs" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea0dcfa4e54eeb516fe454635a95753ddd39acda650ce703031c6973e315dd5" +checksum = "56624a96882bb8c26d61312ae18cb45868e5a9992ea73c58e45c3101e56a1e60" dependencies = [ - "enum-ordinalize-derive", + "asn1-rs-derive", + "asn1-rs-impl", + "displaydoc", + "nom", + "num-traits", + "rusticata-macros", + "thiserror 2.0.17", + "time", ] [[package]] -name = "enum-ordinalize-derive" -version = "4.3.1" +name = "asn1-rs-derive" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff" +checksum = "3109e49b1e4909e9db6515a30c633684d68cdeaa252f215214cb4fa1a5bfee2c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", + "synstructure 0.13.2", ] [[package]] -name = "equivalent" -version = "1.0.2" +name = "asn1-rs-impl" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" +checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", +] [[package]] -name = "errno" -version = "0.3.14" +name = "assert_type_match" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +checksum = "f548ad2c4031f2902e3edc1f29c29e835829437de49562d8eb5dc5584d3a1043" dependencies = [ - "libc", - "windows-sys 0.61.2", + "proc-macro2", + "quote", + "syn 2.0.110", ] [[package]] -name = "fastrand" -version = "2.3.0" +name = "async-broadcast" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +checksum = "7c48ccdbf6ca6b121e0f586cbc0e73ae440e56c67c30fa0873b4e110d9c26d2b" +dependencies = [ + "event-listener 2.5.3", + "futures-core", +] [[package]] -name = "find-msvc-tools" -version = "0.1.4" +name = "async-channel" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" +checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" +dependencies = [ + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] [[package]] -name = "fnv" -version = "1.0.7" +name = "async-compression" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +checksum = "93c1f86859c1af3d514fa19e8323147ff10ea98684e6c7b307912509f50e67b2" +dependencies = [ + "compression-codecs", + "compression-core", + "futures-core", + "pin-project-lite", + "tokio", +] [[package]] -name = "foldhash" -version = "0.1.5" +name = "async-executor" +version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +checksum = "497c00e0fd83a72a79a39fcbd8e3e2f055d6f6c7e025f3b3d91f4f8e76527fb8" +dependencies = [ + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "pin-project-lite", + "slab", +] [[package]] -name = "foreign-types" -version = "0.5.0" +name = "async-fs" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +checksum = "8034a681df4aed8b8edbd7fbe472401ecf009251c8b40556b304567052e294c5" dependencies = [ - "foreign-types-macros", - "foreign-types-shared", + "async-lock", + "blocking", + "futures-lite", ] [[package]] -name = "foreign-types-macros" -version = "0.2.3" +name = "async-lock" +version = "3.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +checksum = "5fd03604047cee9b6ce9de9f70c6cd540a0520c813cbd49bae61f33ab80ed1dc" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.108", + "event-listener 5.4.1", + "event-listener-strategy", + "pin-project-lite", ] [[package]] -name = "foreign-types-shared" -version = "0.3.1" +name = "async-stream" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] [[package]] -name = "form_urlencoded" -version = "1.2.2" +name = "async-stream-impl" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ - "percent-encoding", + "proc-macro2", + "quote", + "syn 2.0.110", ] [[package]] -name = "futures-channel" -version = "0.3.31" +name = "async-task" +version = "4.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" + +[[package]] +name = "async-trait" +version = "0.1.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ - "futures-core", - "futures-sink", + "proc-macro2", + "quote", + "syn 2.0.110", ] [[package]] -name = "futures-core" -version = "0.3.31" +name = "atomic-waker" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] -name = "futures-io" -version = "0.3.31" +name = "atomicow" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" +checksum = "f52e8890bb9844440d0c412fa74b67fd2f14e85248b6e00708059b6da9e5f8bf" +dependencies = [ + "portable-atomic", + "portable-atomic-util", +] [[package]] -name = "futures-macro" -version = "0.3.31" +name = "auto_impl" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +checksum = "ffdcb70bdbc4d478427380519163274ac86e52916e10f0a8889adf0f96d3fee7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] -name = "futures-sink" -version = "0.3.31" +name = "auto_ops" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" +checksum = "7460f7dd8e100147b82a63afca1a20eb6c231ee36b90ba7272e14951cb58af59" [[package]] -name = "futures-task" -version = "0.3.31" +name = "autocfg" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] -name = "futures-util" -version = "0.3.31" +name = "aws-config" +version = "1.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +checksum = "a0149602eeaf915158e14029ba0c78dedb8c08d554b024d54c8f239aab46511d" dependencies = [ - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", + "aws-credential-types", + "aws-runtime", + "aws-sdk-sso", + "aws-sdk-ssooidc", + "aws-sdk-sts", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "fastrand", + "hex", + "http 1.3.1", + "ring", + "time", + "tokio", + "tracing", + "url", + "zeroize", ] [[package]] -name = "game-content" -version = "0.1.0" +name = "aws-credential-types" +version = "1.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b01c9521fa01558f750d183c8c68c81b0155b9d193a4ba7f84c36bd1b6d04a06" dependencies = [ - "anyhow", - "game-core", - "ron", - "serde", - "toml 0.9.8", + "aws-smithy-async", + "aws-smithy-runtime-api", + "aws-smithy-types", + "zeroize", ] [[package]] -name = "game-core" -version = "0.1.0" +name = "aws-lc-rs" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5932a7d9d28b0d2ea34c6b3779d35e3dd6f6345317c34e73438c4f1f29144151" dependencies = [ - "arrayvec", - "bitflags 2.10.0", - "bounded-vector", - "serde", - "thiserror 2.0.17", + "aws-lc-sys", + "zeroize", ] [[package]] -name = "generic-array" -version = "0.14.9" +name = "aws-lc-sys" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" +checksum = "1826f2e4cfc2cd19ee53c42fbf68e2f81ec21108e0b7ecf6a71cf062137360fc" dependencies = [ - "typenum", - "version_check", + "bindgen 0.72.1", + "cc", + "cmake", + "dunce", + "fs_extra", ] [[package]] -name = "getrandom" -version = "0.2.16" +name = "aws-runtime" +version = "1.5.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +checksum = "7ce527fb7e53ba9626fc47824f25e256250556c40d8f81d27dd92aa38239d632" dependencies = [ - "cfg-if", - "js-sys", - "libc", - "wasi", - "wasm-bindgen", + "aws-credential-types", + "aws-sigv4", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "fastrand", + "http 0.2.12", + "http-body 0.4.6", + "percent-encoding", + "pin-project-lite", + "tracing", + "uuid", ] [[package]] -name = "getrandom" -version = "0.3.4" +name = "aws-sdk-kms" +version = "1.95.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +checksum = "0878cf025f9b50d45586fb73578a4323743498db5e12ff6c7b679caad33c4384" dependencies = [ - "cfg-if", - "js-sys", - "libc", - "r-efi", - "wasip2", - "wasm-bindgen", + "aws-credential-types", + "aws-runtime", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "fastrand", + "http 0.2.12", + "regex-lite", + "tracing", ] [[package]] -name = "hashbrown" -version = "0.12.3" +name = "aws-sdk-sso" +version = "1.90.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +checksum = "4f18e53542c522459e757f81e274783a78f8c81acdfc8d1522ee8a18b5fb1c66" +dependencies = [ + "aws-credential-types", + "aws-runtime", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "fastrand", + "http 0.2.12", + "regex-lite", + "tracing", +] [[package]] -name = "hashbrown" -version = "0.15.5" +name = "aws-sdk-ssooidc" +version = "1.92.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +checksum = "532f4d866012ffa724a4385c82e8dd0e59f0ca0e600f3f22d4c03b6824b34e4a" dependencies = [ - "allocator-api2", - "equivalent", - "foldhash", + "aws-credential-types", + "aws-runtime", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "fastrand", + "http 0.2.12", + "regex-lite", + "tracing", ] [[package]] -name = "hashbrown" -version = "0.16.0" +name = "aws-sdk-sts" +version = "1.94.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" +checksum = "1be6fbbfa1a57724788853a623378223fe828fc4c09b146c992f0c95b6256174" +dependencies = [ + "aws-credential-types", + "aws-runtime", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-query", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-smithy-xml", + "aws-types", + "fastrand", + "http 0.2.12", + "regex-lite", + "tracing", +] [[package]] -name = "hashlink" -version = "0.10.0" +name = "aws-sigv4" +version = "1.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" +checksum = "c35452ec3f001e1f2f6db107b6373f1f48f05ec63ba2c5c9fa91f07dad32af11" dependencies = [ - "hashbrown 0.15.5", + "aws-credential-types", + "aws-smithy-http", + "aws-smithy-runtime-api", + "aws-smithy-types", + "bytes", + "form_urlencoded", + "hex", + "hmac", + "http 0.2.12", + "http 1.3.1", + "percent-encoding", + "sha2 0.10.9", + "time", + "tracing", ] [[package]] -name = "heck" -version = "0.5.0" +name = "aws-smithy-async" +version = "1.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +checksum = "127fcfad33b7dfc531141fda7e1c402ac65f88aca5511a4d31e2e3d2cd01ce9c" +dependencies = [ + "futures-util", + "pin-project-lite", + "tokio", +] [[package]] -name = "hex" -version = "0.4.3" +name = "aws-smithy-http" +version = "0.62.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +checksum = "445d5d720c99eed0b4aa674ed00d835d9b1427dd73e04adaf2f94c6b2d6f9fca" +dependencies = [ + "aws-smithy-runtime-api", + "aws-smithy-types", + "bytes", + "bytes-utils", + "futures-core", + "futures-util", + "http 0.2.12", + "http 1.3.1", + "http-body 0.4.6", + "percent-encoding", + "pin-project-lite", + "pin-utils", + "tracing", +] [[package]] -name = "hex-literal" -version = "0.4.1" +name = "aws-smithy-http-client" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" +checksum = "623254723e8dfd535f566ee7b2381645f8981da086b5c4aa26c0c41582bb1d2c" +dependencies = [ + "aws-smithy-async", + "aws-smithy-runtime-api", + "aws-smithy-types", + "h2 0.3.27", + "h2 0.4.12", + "http 0.2.12", + "http 1.3.1", + "http-body 0.4.6", + "hyper 0.14.32", + "hyper 1.8.1", + "hyper-rustls 0.24.2", + "hyper-rustls 0.27.7", + "hyper-util", + "pin-project-lite", + "rustls 0.21.12", + "rustls 0.23.35", + "rustls-native-certs 0.8.2", + "rustls-pki-types", + "tokio", + "tokio-rustls 0.26.4", + "tower 0.5.2", + "tracing", +] [[package]] -name = "http" -version = "1.3.1" +name = "aws-smithy-json" +version = "0.61.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +checksum = "2db31f727935fc63c6eeae8b37b438847639ec330a9161ece694efba257e0c54" dependencies = [ - "bytes", - "fnv", - "itoa", + "aws-smithy-types", ] [[package]] -name = "http-body" -version = "1.0.1" +name = "aws-smithy-observability" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +checksum = "2d1881b1ea6d313f9890710d65c158bdab6fb08c91ea825f74c1c8c357baf4cc" dependencies = [ - "bytes", - "http", + "aws-smithy-runtime-api", ] [[package]] -name = "http-body-util" -version = "0.1.3" +name = "aws-smithy-query" +version = "0.60.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +checksum = "d28a63441360c477465f80c7abac3b9c4d075ca638f982e605b7dc2a2c7156c9" dependencies = [ - "bytes", - "futures-core", - "http", - "http-body", - "pin-project-lite", + "aws-smithy-types", + "urlencoding", ] [[package]] -name = "httparse" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" - -[[package]] -name = "hyper" -version = "1.7.0" +name = "aws-smithy-runtime" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e" +checksum = "0bbe9d018d646b96c7be063dd07987849862b0e6d07c778aad7d93d1be6c1ef0" dependencies = [ - "atomic-waker", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-http-client", + "aws-smithy-observability", + "aws-smithy-runtime-api", + "aws-smithy-types", "bytes", - "futures-channel", - "futures-core", - "http", - "http-body", - "httparse", - "itoa", + "fastrand", + "http 0.2.12", + "http 1.3.1", + "http-body 0.4.6", + "http-body 1.0.1", "pin-project-lite", "pin-utils", - "smallvec", "tokio", - "want", + "tracing", ] [[package]] -name = "hyper-rustls" -version = "0.27.7" +name = "aws-smithy-runtime-api" +version = "1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +checksum = "ec7204f9fd94749a7c53b26da1b961b4ac36bf070ef1e0b94bb09f79d4f6c193" dependencies = [ - "http", - "hyper", - "hyper-util", - "rustls", - "rustls-pki-types", + "aws-smithy-async", + "aws-smithy-types", + "bytes", + "http 0.2.12", + "http 1.3.1", + "pin-project-lite", "tokio", - "tokio-rustls", - "tower-service", - "webpki-roots", + "tracing", + "zeroize", ] [[package]] -name = "hyper-util" -version = "0.1.17" +name = "aws-smithy-types" +version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8" +checksum = "25f535879a207fce0db74b679cfc3e91a3159c8144d717d55f5832aea9eef46e" dependencies = [ - "base64", + "base64-simd", "bytes", - "futures-channel", + "bytes-utils", "futures-core", - "futures-util", - "http", - "http-body", - "hyper", - "ipnet", - "libc", - "percent-encoding", + "http 0.2.12", + "http 1.3.1", + "http-body 0.4.6", + "http-body 1.0.1", + "http-body-util", + "itoa", + "num-integer", "pin-project-lite", - "socket2", + "pin-utils", + "ryu", + "serde", + "time", "tokio", - "tower-service", - "tracing", + "tokio-util", ] [[package]] -name = "iana-time-zone" -version = "0.1.64" +name = "aws-smithy-xml" +version = "0.60.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" +checksum = "eab77cdd036b11056d2a30a7af7b775789fb024bf216acc13884c6c97752ae56" dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "log", - "wasm-bindgen", - "windows-core", + "xmlparser", ] [[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" +name = "aws-types" +version = "1.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +checksum = "d79fb68e3d7fe5d4833ea34dc87d2e97d26d3086cb3da660bb6b1f76d98680b6" dependencies = [ - "cc", + "aws-credential-types", + "aws-smithy-async", + "aws-smithy-runtime-api", + "aws-smithy-types", + "rustc_version 0.4.1", + "tracing", ] [[package]] -name = "icu_collections" -version = "2.0.0" +name = "axum" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" +checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" dependencies = [ - "displaydoc", - "potential_utf", - "yoke", - "zerofrom", - "zerovec", + "async-trait", + "axum-core 0.4.5", + "bytes", + "futures-util", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "hyper 1.8.1", + "hyper-util", + "itoa", + "matchit 0.7.3", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sync_wrapper 1.0.2", + "tokio", + "tower 0.5.2", + "tower-layer", + "tower-service", + "tracing", ] [[package]] -name = "icu_locale_core" -version = "2.0.0" +name = "axum" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" +checksum = "5b098575ebe77cb6d14fc7f32749631a6e44edbef6b796f89b020e99ba20d425" dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", + "axum-core 0.5.5", + "axum-macros", + "base64 0.22.1", + "bytes", + "form_urlencoded", + "futures-util", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "hyper 1.8.1", + "hyper-util", + "itoa", + "matchit 0.8.4", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "serde_core", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sha1", + "sync_wrapper 1.0.2", + "tokio", + "tokio-tungstenite", + "tower 0.5.2", + "tower-layer", + "tower-service", ] [[package]] -name = "icu_normalizer" -version = "2.0.0" +name = "axum-core" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" +checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" dependencies = [ - "displaydoc", - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "zerovec", + "async-trait", + "bytes", + "futures-util", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "mime", + "pin-project-lite", + "rustversion", + "sync_wrapper 1.0.2", + "tower-layer", + "tower-service", + "tracing", ] [[package]] -name = "icu_normalizer_data" -version = "2.0.0" +name = "axum-core" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" +checksum = "59446ce19cd142f8833f856eb31f3eb097812d1479ab224f54d72428ca21ea22" +dependencies = [ + "bytes", + "futures-core", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "mime", + "pin-project-lite", + "sync_wrapper 1.0.2", + "tower-layer", + "tower-service", +] [[package]] -name = "icu_properties" -version = "2.0.1" +name = "axum-macros" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" +checksum = "604fde5e028fea851ce1d8570bbdc034bec850d157f7569d10f347d06808c05c" dependencies = [ - "displaydoc", - "icu_collections", - "icu_locale_core", - "icu_properties_data", - "icu_provider", - "potential_utf", - "zerotrie", - "zerovec", + "proc-macro2", + "quote", + "syn 2.0.110", ] [[package]] -name = "icu_properties_data" -version = "2.0.1" +name = "backoff" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" +checksum = "b62ddb9cb1ec0a098ad4bbf9344d0713fa193ae1a80af55febcff2627b6a00c1" +dependencies = [ + "futures-core", + "getrandom 0.2.16", + "instant", + "pin-project-lite", + "rand 0.8.5", + "tokio", +] [[package]] -name = "icu_provider" -version = "2.0.0" +name = "backtrace" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" +checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" dependencies = [ - "displaydoc", - "icu_locale_core", - "stable_deref_trait", - "tinystr", - "writeable", - "yoke", - "zerofrom", - "zerotrie", - "zerovec", + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object 0.37.3", + "rustc-demangle", + "serde", + "windows-link", ] [[package]] -name = "ident_case" -version = "1.0.1" +name = "base-x" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" +checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" [[package]] -name = "idna" -version = "1.1.0" +name = "base16ct" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" -dependencies = [ - "idna_adapter", - "smallvec", - "utf8_iter", -] +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" [[package]] -name = "idna_adapter" -version = "1.2.1" +name = "base16ct" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base256emoji" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e9430d9a245a77c92176e649af6e275f20839a48389859d1661e9a128d077c" dependencies = [ - "icu_normalizer", - "icu_properties", + "const-str", + "match-lookup", ] [[package]] -name = "include_bytes_aligned" -version = "0.1.4" +name = "base64" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ee796ad498c8d9a1d68e477df8f754ed784ef875de1414ebdaf169f70a6a784" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] -name = "indexmap" -version = "1.9.3" +name = "base64" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", - "serde", -] +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] -name = "indexmap" -version = "2.12.0" +name = "base64-simd" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f" +checksum = "339abbe78e73178762e23bea9dfd08e697eb3f3301cd4be981c0f78ba5859195" dependencies = [ - "equivalent", - "hashbrown 0.16.0", - "serde", - "serde_core", + "outref", + "vsimd", ] [[package]] -name = "indoc" -version = "2.0.7" +name = "base64ct" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706" -dependencies = [ - "rustversion", -] +checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" [[package]] -name = "instability" -version = "0.3.9" +name = "bcs" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435d80800b936787d62688c927b6490e887c7ef5ff9ce922c6c6050fca75eb9a" +checksum = "85b6598a2f5d564fb7855dc6b06fd1c38cff5a72bd8b863a4d021938497b440a" dependencies = [ - "darling 0.20.11", - "indoc", - "proc-macro2", - "quote", - "syn 2.0.108", + "serde", + "thiserror 1.0.69", ] [[package]] -name = "ipnet" -version = "2.11.0" +name = "bech32" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" +checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" [[package]] -name = "iri-string" -version = "0.7.8" +name = "beef" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" + +[[package]] +name = "behavior-tree" +version = "0.1.0" + +[[package]] +name = "bellpepper" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" +checksum = "9ae286c2cb403324ab644c7cc68dceb25fe52ca9429908a726d7ed272c1edf7b" dependencies = [ - "memchr", - "serde", + "bellpepper-core", + "byteorder", + "ff 0.13.1", ] [[package]] -name = "is_terminal_polyfill" -version = "1.70.2" +name = "bellpepper-core" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" +checksum = "1d8abb418570756396d722841b19edfec21d4e89e1cf8990610663040ecb1aea" +dependencies = [ + "blake2s_simd", + "byteorder", + "ff 0.13.1", + "serde", + "thiserror 1.0.69", +] [[package]] -name = "itertools" -version = "0.13.0" +name = "better_any" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +checksum = "b359aebd937c17c725e19efcb661200883f04c49c53e7132224dac26da39d4a0" dependencies = [ - "either", + "better_typeid_derive", ] [[package]] -name = "itertools" -version = "0.14.0" +name = "better_typeid_derive" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +checksum = "3deeecb812ca5300b7d3f66f730cc2ebd3511c3d36c691dd79c165d5b19a26e3" dependencies = [ - "either", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] -name = "itoa" -version = "1.0.15" +name = "bevy" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +checksum = "2eaad7fe854258047680c51c3cacb804468553c04241912f6254c841c67c0198" +dependencies = [ + "bevy_internal", +] [[package]] -name = "js-sys" -version = "0.3.81" +name = "bevy_a11y" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305" +checksum = "245a938f754f70a380687b89f1c4dac75b62d58fae90ae969fcfb8ecd91ed879" dependencies = [ - "once_cell", - "wasm-bindgen", + "accesskit", + "bevy_app", + "bevy_derive", + "bevy_ecs", + "bevy_reflect", ] [[package]] -name = "keccak" -version = "0.1.5" +name = "bevy_app" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +checksum = "a0ac033a388b8699d241499a43783a09e6a3bab2430f1297c6bd4974095efb3f" dependencies = [ - "cpufeatures", + "bevy_derive", + "bevy_ecs", + "bevy_reflect", + "bevy_tasks", + "bevy_utils", + "console_error_panic_hook", + "ctrlc", + "derive_more 1.0.0", + "downcast-rs", + "wasm-bindgen", + "web-sys", ] [[package]] -name = "lazy-regex" -version = "3.4.1" +name = "bevy_asset" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60c7310b93682b36b98fa7ea4de998d3463ccbebd94d935d6b48ba5b6ffa7126" +checksum = "73fd901b3be016088c4dda2f628bda96b7cb578b9bc8ae684bbf30bec0a9483e" dependencies = [ - "lazy-regex-proc_macros", - "once_cell", - "regex", + "async-broadcast", + "async-fs", + "async-lock", + "atomicow", + "bevy_app", + "bevy_asset_macros", + "bevy_ecs", + "bevy_reflect", + "bevy_tasks", + "bevy_utils", + "bevy_window", + "bitflags 2.10.0", + "blake3", + "crossbeam-channel", + "derive_more 1.0.0", + "disqualified", + "downcast-rs", + "either", + "futures-io", + "futures-lite", + "js-sys", + "parking_lot", + "ron 0.8.1", + "serde", + "stackfuture", + "uuid", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", ] [[package]] -name = "lazy-regex-proc_macros" -version = "3.4.1" +name = "bevy_asset_macros" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ba01db5ef81e17eb10a5e0f2109d1b3a3e29bac3070fdbd7d156bf7dbd206a1" +checksum = "6725a785789ece8d8c73bba25fdac5e50494d959530e89565bbcea9f808b7181" dependencies = [ + "bevy_macro_utils", "proc-macro2", "quote", - "regex", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] -name = "lazy_static" -version = "1.5.0" +name = "bevy_color" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +checksum = "a87b7137ffa9844ae542043769fb98c35efbf2f8a8429ff2a73d8ef30e58baaa" dependencies = [ - "spin", + "bevy_math", + "bevy_reflect", + "bytemuck", + "derive_more 1.0.0", + "encase", + "serde", + "wgpu-types", ] [[package]] -name = "libc" -version = "0.2.177" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" - -[[package]] -name = "libm" -version = "0.2.15" +name = "bevy_core" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" +checksum = "1e9ce8da8e4016f63c1d361b52e61aaf4348c569829c74f1a5bbedfd8d3d57a3" +dependencies = [ + "bevy_app", + "bevy_ecs", + "bevy_reflect", + "bevy_tasks", + "bevy_utils", + "uuid", +] [[package]] -name = "libredox" -version = "0.1.10" +name = "bevy_core_pipeline" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" +checksum = "ee0ff0f4723f30a5a6578915dbfe0129f2befaec8438dde70ac1fb363aee01f5" dependencies = [ + "bevy_app", + "bevy_asset", + "bevy_color", + "bevy_core", + "bevy_derive", + "bevy_ecs", + "bevy_image", + "bevy_math", + "bevy_reflect", + "bevy_render", + "bevy_transform", + "bevy_utils", + "bevy_window", "bitflags 2.10.0", - "libc", + "derive_more 1.0.0", + "nonmax", + "radsort", + "serde", + "smallvec", ] [[package]] -name = "linux-raw-sys" -version = "0.4.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" - -[[package]] -name = "linux-raw-sys" -version = "0.11.0" +name = "bevy_derive" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" +checksum = "57d94761ce947b0a2402fd949fe1e7a5b1535293130ba4cd9893be6295d4680a" +dependencies = [ + "bevy_macro_utils", + "quote", + "syn 2.0.110", +] [[package]] -name = "litemap" -version = "0.8.0" +name = "bevy_diagnostic" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" +checksum = "5e83c65979f063b593917ab9b1d7328c5854dba4b6ddf1ab78156c0105831fdf" +dependencies = [ + "bevy_app", + "bevy_core", + "bevy_ecs", + "bevy_tasks", + "bevy_time", + "bevy_utils", + "const-fnv1a-hash", +] [[package]] -name = "litrs" -version = "0.4.2" +name = "bevy_ecs" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed" +checksum = "ecb64e8f2fe95aa2f8b3e96d09acd23021257ce4a8c942f4c38dcbeaf721955c" +dependencies = [ + "arrayvec", + "bevy_ecs_macros", + "bevy_ptr", + "bevy_reflect", + "bevy_tasks", + "bevy_utils", + "bitflags 2.10.0", + "concurrent-queue", + "derive_more 1.0.0", + "disqualified", + "fixedbitset 0.5.7", + "nonmax", + "petgraph 0.6.5", + "serde", + "smallvec", +] [[package]] -name = "lock_api" -version = "0.4.14" +name = "bevy_ecs_macros" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +checksum = "f453adf07712b39826bc5845e5b0887ce03204ee8359bbe6b40a9afda60564a1" dependencies = [ - "scopeguard", + "bevy_macro_utils", + "proc-macro2", + "quote", + "syn 2.0.110", ] [[package]] -name = "log" -version = "0.4.28" +name = "bevy_encase_derive" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" +checksum = "f37ad69d36bb9e8479a88d481ef9748f5d7ab676040531d751d3a44441dcede7" +dependencies = [ + "bevy_macro_utils", + "encase_derive_impl", +] [[package]] -name = "lru" -version = "0.12.5" +name = "bevy_gizmos" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" +checksum = "c1614516d0922ad60e87cc39658422286ed684aaf4b3162d25051bc105eed814" dependencies = [ - "hashbrown 0.15.5", + "bevy_app", + "bevy_asset", + "bevy_color", + "bevy_core_pipeline", + "bevy_ecs", + "bevy_gizmos_macros", + "bevy_image", + "bevy_math", + "bevy_reflect", + "bevy_render", + "bevy_sprite", + "bevy_time", + "bevy_transform", + "bevy_utils", + "bytemuck", ] [[package]] -name = "lru-slab" -version = "0.1.2" +name = "bevy_gizmos_macros" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" +checksum = "0edb9e0dca64e0fc9d6b1d9e6e2178396e339e3e2b9f751e2504e3ea4ddf4508" +dependencies = [ + "bevy_macro_utils", + "proc-macro2", + "quote", + "syn 2.0.110", +] [[package]] -name = "malloc_buf" -version = "0.0.6" +name = "bevy_hierarchy" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +checksum = "19ced04e04437d0a439fe4722544c2a4678c1fe3412b57ee489d817c11884045" dependencies = [ - "libc", + "bevy_app", + "bevy_core", + "bevy_ecs", + "bevy_reflect", + "bevy_utils", + "disqualified", + "smallvec", ] [[package]] -name = "matchers" -version = "0.2.0" +name = "bevy_image" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +checksum = "4b384d1ce9c87f6151292a76233897a628c2a50b3560487c4d74472225d49826" dependencies = [ - "regex-automata", + "bevy_asset", + "bevy_color", + "bevy_math", + "bevy_reflect", + "bevy_utils", + "bitflags 2.10.0", + "bytemuck", + "derive_more 1.0.0", + "futures-lite", + "image", + "serde", + "wgpu", +] + +[[package]] +name = "bevy_input" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52589939ca09695c69d629d166c5edf1759feaaf8f2078904aae9c33d08f5c3" +dependencies = [ + "bevy_app", + "bevy_core", + "bevy_ecs", + "bevy_math", + "bevy_reflect", + "bevy_utils", + "derive_more 1.0.0", + "smol_str", +] + +[[package]] +name = "bevy_internal" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1e0c1d980d276e11558184d0627c8967ad8b70dab3e54a0f377bb53b98515b6" +dependencies = [ + "bevy_a11y", + "bevy_app", + "bevy_asset", + "bevy_color", + "bevy_core", + "bevy_core_pipeline", + "bevy_derive", + "bevy_diagnostic", + "bevy_ecs", + "bevy_gizmos", + "bevy_hierarchy", + "bevy_image", + "bevy_input", + "bevy_log", + "bevy_math", + "bevy_picking", + "bevy_ptr", + "bevy_reflect", + "bevy_render", + "bevy_scene", + "bevy_sprite", + "bevy_tasks", + "bevy_text", + "bevy_time", + "bevy_transform", + "bevy_ui", + "bevy_utils", + "bevy_window", + "bevy_winit", +] + +[[package]] +name = "bevy_log" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b381a22e01f24af51536ef1eace94298dd555d06ffcf368125d16317f5f179cb" +dependencies = [ + "android_log-sys", + "bevy_app", + "bevy_ecs", + "bevy_utils", + "tracing-log", + "tracing-oslog", + "tracing-subscriber 0.3.20", + "tracing-wasm", ] [[package]] -name = "maybe-async" -version = "0.2.10" +name = "bevy_macro_utils" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cf92c10c7e361d6b99666ec1c6f9805b0bea2c3bd8c78dc6fe98ac5bd78db11" +checksum = "8bb6ded1ddc124ea214f6a2140e47a78d1fe79b0638dad39419cdeef2e1133f1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", + "toml_edit 0.22.27", ] [[package]] -name = "memchr" -version = "2.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" - -[[package]] -name = "memmap2" -version = "0.9.9" +name = "bevy_math" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "744133e4a0e0a658e1374cf3bf8e415c4052a15a111acd372764c55b4177d490" +checksum = "1c2650169161b64f9a93e41f13253701fdf971dc95265ed667d17bea6d2a334f" dependencies = [ - "libc", + "bevy_reflect", + "derive_more 1.0.0", + "glam", + "itertools 0.13.0", + "rand 0.8.5", + "rand_distr", + "serde", + "smallvec", ] [[package]] -name = "merlin" -version = "3.0.0" +name = "bevy_mesh" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d" +checksum = "760f3c41b4c61a5f0d956537f454c49f79b8ed0fd0781b1a879ead8e69d95283" dependencies = [ - "byteorder", - "keccak", - "rand_core 0.6.4", - "zeroize", + "bevy_asset", + "bevy_derive", + "bevy_ecs", + "bevy_image", + "bevy_math", + "bevy_mikktspace", + "bevy_reflect", + "bevy_transform", + "bevy_utils", + "bitflags 2.10.0", + "bytemuck", + "derive_more 1.0.0", + "hexasphere", + "serde", + "wgpu", ] [[package]] -name = "metal" -version = "0.29.0" +name = "bevy_mikktspace" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ecfd3296f8c56b7c1f6fbac3c71cefa9d78ce009850c45000015f206dc7fa21" +checksum = "226f663401069ded4352ed1472a85bb1f43e2b7305d6a50e53a4f6508168e380" dependencies = [ - "bitflags 2.10.0", - "block", - "core-graphics-types", - "foreign-types", - "log", - "objc", - "paste", + "glam", ] [[package]] -name = "mio" -version = "1.0.4" +name = "bevy_picking" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +checksum = "2091a495c0f9c8962abb1e30f9d99696296c332b407e1f6fe1fe28aab96a8629" dependencies = [ - "libc", - "log", - "wasi", - "windows-sys 0.59.0", + "bevy_app", + "bevy_asset", + "bevy_derive", + "bevy_ecs", + "bevy_hierarchy", + "bevy_input", + "bevy_math", + "bevy_reflect", + "bevy_render", + "bevy_time", + "bevy_transform", + "bevy_utils", + "bevy_window", + "uuid", ] [[package]] -name = "no_std_strings" -version = "0.1.3" +name = "bevy_ptr" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5b0c77c1b780822bc749a33e39aeb2c07584ab93332303babeabb645298a76e" +checksum = "89fe0b0b919146939481a3a7c38864face2c6d0fd2c73ab3d430dc693ecd9b11" [[package]] -name = "nu-ansi-term" -version = "0.50.3" +name = "bevy_reflect" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +checksum = "3ddbca0a39e88eff2c301dc794ee9d73a53f4b08d47b2c9b5a6aac182fae6217" dependencies = [ - "windows-sys 0.61.2", + "assert_type_match", + "bevy_ptr", + "bevy_reflect_derive", + "bevy_utils", + "derive_more 1.0.0", + "disqualified", + "downcast-rs", + "erased-serde 0.4.9", + "glam", + "serde", + "smallvec", + "smol_str", + "uuid", ] [[package]] -name = "num-bigint" -version = "0.4.6" +name = "bevy_reflect_derive" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +checksum = "d62affb769db17d34ad0b75ff27eca94867e2acc8ea350c5eca97d102bd98709" dependencies = [ - "num-integer", - "num-traits", + "bevy_macro_utils", + "proc-macro2", + "quote", + "syn 2.0.110", + "uuid", +] + +[[package]] +name = "bevy_render" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4aa9d7df5c2b65540093b8402aceec0a55d67b54606e57ce2969abe280b4c48" +dependencies = [ + "async-channel", + "bevy_app", + "bevy_asset", + "bevy_color", + "bevy_core", + "bevy_derive", + "bevy_diagnostic", + "bevy_ecs", + "bevy_encase_derive", + "bevy_hierarchy", + "bevy_image", + "bevy_math", + "bevy_mesh", + "bevy_reflect", + "bevy_render_macros", + "bevy_tasks", + "bevy_time", + "bevy_transform", + "bevy_utils", + "bevy_window", + "bytemuck", + "codespan-reporting", + "derive_more 1.0.0", + "downcast-rs", + "encase", + "futures-lite", + "image", + "js-sys", + "naga", + "naga_oil", + "nonmax", + "offset-allocator", + "send_wrapper", + "serde", + "smallvec", + "wasm-bindgen", + "web-sys", + "wgpu", ] [[package]] -name = "num-bigint-dig" -version = "0.8.4" +name = "bevy_render_macros" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +checksum = "3469307d1b5ca5c37b7f9269be033845357412ebad33eace46826e59da592f66" dependencies = [ - "byteorder", - "lazy_static", - "libm", - "num-integer", - "num-iter", - "num-traits", - "rand 0.8.5", - "smallvec", - "zeroize", + "bevy_macro_utils", + "proc-macro2", + "quote", + "syn 2.0.110", ] [[package]] -name = "num-conv" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" - -[[package]] -name = "num-integer" -version = "0.1.46" +name = "bevy_scene" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +checksum = "bdfe819202aa97bbb206d79fef83504b34d45529810563aafc2fe02cc10e3ee4" dependencies = [ - "num-traits", + "bevy_app", + "bevy_asset", + "bevy_derive", + "bevy_ecs", + "bevy_hierarchy", + "bevy_reflect", + "bevy_render", + "bevy_transform", + "bevy_utils", + "derive_more 1.0.0", + "serde", + "uuid", ] [[package]] -name = "num-iter" -version = "0.1.45" +name = "bevy_sprite" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +checksum = "27411a31704117002787c9e8cc1f2f89babf5e67572508aa029366d4643f8d01" dependencies = [ - "autocfg", - "num-integer", - "num-traits", + "bevy_app", + "bevy_asset", + "bevy_color", + "bevy_core_pipeline", + "bevy_derive", + "bevy_ecs", + "bevy_image", + "bevy_math", + "bevy_picking", + "bevy_reflect", + "bevy_render", + "bevy_transform", + "bevy_utils", + "bevy_window", + "bitflags 2.10.0", + "bytemuck", + "derive_more 1.0.0", + "fixedbitset 0.5.7", + "guillotiere", + "nonmax", + "radsort", + "rectangle-pack", ] [[package]] -name = "num-traits" -version = "0.2.19" +name = "bevy_tasks" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +checksum = "028630ddc355563bd567df1076db3515858aa26715ddf7467d2086f9b40e5ab1" dependencies = [ - "autocfg", - "libm", + "async-channel", + "async-executor", + "concurrent-queue", + "futures-channel", + "futures-lite", + "pin-project", + "wasm-bindgen-futures", ] [[package]] -name = "num_enum" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c" -dependencies = [ - "num_enum_derive", - "rustversion", +name = "bevy_text" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "872b0b627cedf6d1bd97b75bc4d59c16f67afdd4f2fed8f7d808a258d6cb982e" +dependencies = [ + "bevy_app", + "bevy_asset", + "bevy_color", + "bevy_derive", + "bevy_ecs", + "bevy_hierarchy", + "bevy_image", + "bevy_math", + "bevy_reflect", + "bevy_render", + "bevy_sprite", + "bevy_transform", + "bevy_utils", + "bevy_window", + "cosmic-text", + "derive_more 1.0.0", + "serde", + "smallvec", + "sys-locale", + "unicode-bidi", ] [[package]] -name = "num_enum_derive" -version = "0.7.5" +name = "bevy_time" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" +checksum = "1b2051ec56301b994f7c182a2a6eb1490038149ad46d95eee715e1a922acdfd9" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.108", + "bevy_app", + "bevy_ecs", + "bevy_reflect", + "bevy_utils", + "crossbeam-channel", ] [[package]] -name = "objc" -version = "0.2.7" +name = "bevy_transform" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +checksum = "a8109b1234b0e58931f51df12bc8895daa69298575cf92da408848f79a4ce201" dependencies = [ - "malloc_buf", + "bevy_app", + "bevy_ecs", + "bevy_hierarchy", + "bevy_math", + "bevy_reflect", + "derive_more 1.0.0", ] [[package]] -name = "once_cell" -version = "1.21.3" +name = "bevy_ui" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +checksum = "e534590222d044c875bf3511e5d0b3da78889bb21ad797953484ce011af77b46" +dependencies = [ + "accesskit", + "bevy_a11y", + "bevy_app", + "bevy_asset", + "bevy_color", + "bevy_core_pipeline", + "bevy_derive", + "bevy_ecs", + "bevy_hierarchy", + "bevy_image", + "bevy_input", + "bevy_math", + "bevy_picking", + "bevy_reflect", + "bevy_render", + "bevy_sprite", + "bevy_text", + "bevy_transform", + "bevy_utils", + "bevy_window", + "bytemuck", + "derive_more 1.0.0", + "nonmax", + "smallvec", + "taffy", +] [[package]] -name = "once_cell_polyfill" -version = "1.70.2" +name = "bevy_utils" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" +checksum = "63c2174d43a0de99f863c98a472370047a2bfa7d1e5cec8d9d647fb500905d9d" +dependencies = [ + "ahash", + "bevy_utils_proc_macros", + "getrandom 0.2.16", + "hashbrown 0.14.5", + "thread_local", + "tracing", + "web-time", +] [[package]] -name = "option-ext" -version = "0.2.0" +name = "bevy_utils_proc_macros" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +checksum = "94847541f6dd2e28f54a9c2b0e857da5f2631e2201ebc25ce68781cdcb721391" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", +] [[package]] -name = "parking_lot" -version = "0.12.5" +name = "bevy_window" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +checksum = "c1e1e7c6713c04404a3e7cede48a9c47b76c30efc764664ec1246147f6fb9878" dependencies = [ - "lock_api", - "parking_lot_core", + "android-activity", + "bevy_a11y", + "bevy_app", + "bevy_ecs", + "bevy_input", + "bevy_math", + "bevy_reflect", + "bevy_utils", + "raw-window-handle", + "smol_str", ] [[package]] -name = "parking_lot_core" -version = "0.9.12" +name = "bevy_winit" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +checksum = "e158a73d6d896b1600a61bc115017707ecb467d1a5ad49231c5e58294f6f6e13" dependencies = [ + "accesskit", + "accesskit_winit", + "approx", + "bevy_a11y", + "bevy_app", + "bevy_derive", + "bevy_ecs", + "bevy_hierarchy", + "bevy_input", + "bevy_log", + "bevy_math", + "bevy_reflect", + "bevy_tasks", + "bevy_utils", + "bevy_window", "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-link", + "crossbeam-channel", + "raw-window-handle", + "wasm-bindgen", + "web-sys", + "winit", ] [[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - -[[package]] -name = "pem-rfc7468" -version = "0.7.0" +name = "bincode" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" dependencies = [ - "base64ct", + "serde", ] [[package]] -name = "percent-encoding" -version = "2.3.2" +name = "bindgen" +version = "0.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" +checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" +dependencies = [ + "bitflags 2.10.0", + "cexpr", + "clang-sys", + "itertools 0.13.0", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash 1.1.0", + "shlex", + "syn 2.0.110", +] [[package]] -name = "pin-project-lite" -version = "0.2.16" +name = "bindgen" +version = "0.72.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" +checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" +dependencies = [ + "bitflags 2.10.0", + "cexpr", + "clang-sys", + "itertools 0.13.0", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash 2.1.1", + "shlex", + "syn 2.0.110", +] [[package]] -name = "pin-utils" -version = "0.1.0" +name = "bip32" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +checksum = "b30ed1d6f8437a487a266c8293aeb95b61a23261273e3e02912cdb8b68bf798b" +dependencies = [ + "bs58 0.4.0", + "hmac", + "k256 0.11.6", + "once_cell", + "pbkdf2", + "rand_core 0.6.4", + "ripemd", + "sha2 0.10.9", + "subtle", + "zeroize", +] [[package]] -name = "pkcs1" -version = "0.7.5" +name = "bit-set" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" dependencies = [ - "der", - "pkcs8", - "spki", + "bit-vec 0.6.3", ] [[package]] -name = "pkcs8" -version = "0.10.2" +name = "bit-set" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" dependencies = [ - "der", - "spki", + "bit-vec 0.8.0", ] [[package]] -name = "postcard" -version = "1.1.3" +name = "bit-vec" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24" -dependencies = [ - "cobs", - "embedded-io 0.4.0", - "embedded-io 0.6.1", - "serde", -] +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" [[package]] -name = "potential_utf" +name = "bit-vec" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" + +[[package]] +name = "bitcoin-io" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" -dependencies = [ - "zerovec", -] +checksum = "0b47c4ab7a93edb0c7198c5535ed9b52b63095f4e9b45279c6736cec4b856baf" [[package]] -name = "powerfmt" -version = "0.2.0" +name = "bitcoin-private" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" +checksum = "73290177011694f38ec25e165d0387ab7ea749a4b81cd4c80dae5988229f7a57" [[package]] -name = "ppv-lite86" -version = "0.2.21" +name = "bitcoin_hashes" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +checksum = "5d7066118b13d4b20b23645932dfb3a81ce7e29f95726c2036fa33cd7b092501" dependencies = [ - "zerocopy", + "bitcoin-private", ] [[package]] -name = "proc-macro-crate" -version = "3.4.0" +name = "bitcoin_hashes" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" +checksum = "bb18c03d0db0247e147a21a6faafd5a7eb851c743db062de72018b6b7e8e4d16" dependencies = [ - "toml_edit 0.23.7", + "bitcoin-io", + "hex-conservative", ] [[package]] -name = "proc-macro2" -version = "1.0.102" +name = "bitflags" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e0f6df8eaa422d97d72edcd152e1451618fed47fabbdbd5a8864167b1d4aff7" -dependencies = [ - "unicode-ident", -] +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] -name = "proc-macro2-diagnostics" -version = "0.10.1" +name = "bitflags" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.108", - "version_check", - "yansi", + "serde_core", ] [[package]] -name = "proptest" -version = "1.8.0" +name = "bitmaps" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bb0be07becd10686a0bb407298fb425360a5c44a663774406340c59a22de4ce" +checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2" dependencies = [ - "bitflags 2.10.0", - "num-traits", - "rand 0.9.2", - "rand_chacha 0.9.0", - "rand_xorshift", - "unarray", + "typenum", ] [[package]] -name = "prost" -version = "0.13.5" +name = "bitvec" +version = "0.20.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5" +checksum = "7774144344a4faa177370406a7ff5f1da24303817368584c6206c8303eb07848" dependencies = [ - "bytes", - "prost-derive", + "funty 1.1.0", + "radium 0.6.2", + "tap", + "wyz 0.2.0", ] [[package]] -name = "prost-derive" -version = "0.13.5" +name = "bitvec" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" dependencies = [ - "anyhow", - "itertools 0.14.0", - "proc-macro2", - "quote", - "syn 2.0.108", + "funty 2.0.0", + "radium 0.7.0", + "tap", + "wyz 0.5.1", ] [[package]] -name = "quinn" -version = "0.11.9" +name = "blake2" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" dependencies = [ - "bytes", - "cfg_aliases", - "pin-project-lite", - "quinn-proto", - "quinn-udp", - "rustc-hash", - "rustls", - "socket2", - "thiserror 2.0.17", - "tokio", - "tracing", - "web-time", + "digest 0.10.7", ] [[package]] -name = "quinn-proto" -version = "0.11.13" +name = "blake2b_simd" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" +checksum = "06e903a20b159e944f91ec8499fe1e55651480c541ea0a584f5d967c49ad9d99" dependencies = [ - "bytes", - "getrandom 0.3.4", - "lru-slab", - "rand 0.9.2", - "ring", - "rustc-hash", - "rustls", - "rustls-pki-types", - "slab", - "thiserror 2.0.17", - "tinyvec", - "tracing", - "web-time", + "arrayref", + "arrayvec", + "constant_time_eq", ] [[package]] -name = "quinn-udp" -version = "0.5.14" +name = "blake2s_simd" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" +checksum = "e90f7deecfac93095eb874a40febd69427776e24e1bd7f87f33ac62d6f0174df" dependencies = [ - "cfg_aliases", - "libc", - "once_cell", - "socket2", - "tracing", - "windows-sys 0.60.2", + "arrayref", + "arrayvec", + "constant_time_eq", ] [[package]] -name = "quote" -version = "1.0.41" +name = "blake3" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" +checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0" dependencies = [ - "proc-macro2", + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", ] [[package]] -name = "r-efi" -version = "5.3.0" +name = "block" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" [[package]] -name = "rand" -version = "0.8.5" +name = "block-buffer" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "rand_chacha 0.3.1", - "rand_core 0.6.4", + "generic-array 0.14.7", ] [[package]] -name = "rand" -version = "0.9.2" +name = "block-buffer" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "rand_chacha 0.9.0", - "rand_core 0.9.3", + "generic-array 0.14.7", ] [[package]] -name = "rand_chacha" -version = "0.3.1" +name = "block-padding" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", + "generic-array 0.14.7", ] [[package]] -name = "rand_chacha" -version = "0.9.0" +name = "block2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" dependencies = [ - "ppv-lite86", - "rand_core 0.9.3", + "objc2 0.5.2", ] [[package]] -name = "rand_core" -version = "0.6.4" +name = "block2" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" dependencies = [ - "getrandom 0.2.16", + "objc2 0.6.3", ] [[package]] -name = "rand_core" -version = "0.9.3" +name = "blocking" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21" dependencies = [ - "getrandom 0.3.4", + "async-channel", + "async-task", + "futures-io", + "futures-lite", + "piper", ] [[package]] -name = "rand_xorshift" -version = "0.4.0" +name = "bls12_381" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" +checksum = "a3c196a77437e7cc2fb515ce413a6401291578b5afc8ecb29a3c7ab957f05941" dependencies = [ - "rand_core 0.9.3", + "ff 0.12.1", + "group 0.12.1", + "pairing 0.22.0", + "rand_core 0.6.4", + "subtle", ] [[package]] -name = "ratatui" -version = "0.29.0" +name = "blst" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabd94c2f37801c20583fc49dd5cd6b0ba68c716787c2dd6ed18571e1e63117b" +checksum = "dcdb4c7013139a150f9fc55d123186dbfaba0d912817466282c73ac49e71fb45" dependencies = [ - "bitflags 2.10.0", - "cassowary", - "compact_str", - "crossterm 0.28.1", - "indoc", - "instability", - "itertools 0.13.0", - "lru", - "paste", - "strum 0.26.3", - "unicode-segmentation", - "unicode-truncate", - "unicode-width 0.2.0", + "cc", + "glob", + "threadpool", + "zeroize", ] [[package]] -name = "redox_syscall" -version = "0.5.18" +name = "blstrs" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +checksum = "7a8a8ed6fefbeef4a8c7b460e4110e12c5e22a5b7cf32621aae6ad650c4dcf29" dependencies = [ - "bitflags 2.10.0", + "blst", + "byte-slice-cast", + "ff 0.13.1", + "group 0.13.0", + "pairing 0.23.0", + "rand_core 0.6.4", + "serde", + "subtle", ] [[package]] -name = "redox_users" -version = "0.5.2" +name = "bnum" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" +checksum = "119771309b95163ec7aaf79810da82f7cd0599c19722d48b9c03894dca833966" + +[[package]] +name = "bonsai-sdk" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21055e2f49cbbdbfe9f8f96d597c5527b0c6ab7933341fdc2f147180e48a988e" dependencies = [ - "getrandom 0.2.16", - "libredox", + "duplicate", + "maybe-async", + "reqwest 0.12.24", + "serde", "thiserror 2.0.17", ] [[package]] -name = "ref-cast" -version = "1.0.25" +name = "borsh" +version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" +checksum = "ad8646f98db542e39fc66e68a20b2144f6a732636df7c2354e74645faaa433ce" dependencies = [ - "ref-cast-impl", + "borsh-derive", + "cfg_aliases 0.2.1", ] [[package]] -name = "ref-cast-impl" -version = "1.0.25" +name = "borsh-derive" +version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" +checksum = "fdd1d3c0c2f5833f22386f252fe8ed005c7f59fdcddeef025c01b4c3b9fd9ac3" dependencies = [ + "once_cell", + "proc-macro-crate 3.4.0", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] -name = "regex" -version = "1.12.2" +name = "bounded-vector" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +checksum = "959c8d75c1db5108c22823ea3f0344f147ce330942c8aaadf836e1453af63206" dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", + "serde", + "thiserror 2.0.17", ] [[package]] -name = "regex-automata" -version = "0.4.13" +name = "brotli" +version = "8.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +checksum = "4bd8b9603c7aa97359dbd97ecf258968c95f3adddd6db2f7e7a5bef101c84560" dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", ] [[package]] -name = "regex-syntax" -version = "0.8.8" +name = "brotli-decompressor" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" +checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] [[package]] -name = "reqwest" -version = "0.12.24" +name = "bs58" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d0946410b9f7b082a427e4ef5c8ff541a88b357bc6c637c40db3a68ac70a36f" +checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" dependencies = [ - "base64", - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "http", - "http-body", - "http-body-util", - "hyper", - "hyper-rustls", - "hyper-util", - "js-sys", - "log", - "percent-encoding", - "pin-project-lite", - "quinn", - "rustls", - "rustls-pki-types", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "tokio", - "tokio-rustls", - "tokio-util", - "tower", - "tower-http", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-streams", - "web-sys", - "webpki-roots", + "sha2 0.9.9", ] [[package]] -name = "ring" -version = "0.17.14" +name = "bs58" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" dependencies = [ - "cc", - "cfg-if", - "getrandom 0.2.16", - "libc", - "untrusted", - "windows-sys 0.52.0", + "tinyvec", ] [[package]] -name = "risc0-binfmt" -version = "3.0.2" +name = "bumpalo" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c8f97f81bcdead4101bca06469ecef481a2695cd04e7e877b49dea56a7f6f2a" -dependencies = [ - "anyhow", - "borsh", - "bytemuck", - "derive_more", - "elf", - "lazy_static", - "postcard", - "rand 0.9.2", - "risc0-zkp", - "risc0-zkvm-platform", - "ruint", - "semver", - "serde", - "tracing", -] +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] -name = "risc0-build" -version = "3.0.3" +name = "byte-slice-cast" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bbb512d728e011d03ce0958ca7954624ee13a215bcafd859623b3c63b2a3f60" -dependencies = [ - "anyhow", - "cargo_metadata", - "derive_builder", - "dirs", - "docker-generate", - "hex", - "risc0-binfmt", - "risc0-zkos-v1compat", - "risc0-zkp", - "risc0-zkvm-platform", - "rzup", - "semver", - "serde", - "serde_json", - "stability", - "tempfile", -] +checksum = "7575182f7272186991736b70173b0ea045398f984bf5ebbb3804736ce1330c9d" [[package]] -name = "risc0-circuit-keccak" -version = "4.0.2" +name = "bytecount" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f195f865ac1afdc21a172d7756fdcc21be18e13eb01d78d3d7f2b128fa881ba" -dependencies = [ - "anyhow", - "bytemuck", - "paste", - "risc0-binfmt", - "risc0-circuit-recursion", - "risc0-core", - "risc0-zkp", - "tracing", -] +checksum = "175812e0be2bccb6abe50bb8d566126198344f707e304f45c648fd8f2cc0365e" [[package]] -name = "risc0-circuit-recursion" -version = "4.0.2" +name = "bytemuck" +version = "1.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dca8f15c8abc0fd8c097aa7459879110334d191c63dd51d4c28881c4a497279e" +checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" dependencies = [ - "anyhow", - "bytemuck", - "hex", - "metal", - "risc0-core", - "risc0-zkp", - "tracing", + "bytemuck_derive", ] [[package]] -name = "risc0-circuit-rv32im" -version = "4.0.2" +name = "bytemuck_derive" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae1b0689f4a270a2f247b04397ebb431b8f64fe5170e98ee4f9d71bd04825205" +checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" dependencies = [ - "anyhow", - "bit-vec", - "bytemuck", - "derive_more", - "paste", - "risc0-binfmt", - "risc0-core", - "risc0-zkp", - "serde", - "tracing", + "proc-macro2", + "quote", + "syn 2.0.110", ] [[package]] -name = "risc0-core" -version = "3.0.0" +name = "byteorder" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80f2723fedace48c6c5a505bd8f97ac4e1712bc4cb769083e10536d862b66987" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + +[[package]] +name = "bytes" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" dependencies = [ - "bytemuck", - "rand_core 0.9.3", + "serde", ] [[package]] -name = "risc0-groth16" -version = "3.0.2" +name = "bytes-utils" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "724285dc79604abfb2d40feaefe3e335420a6b293511661f77d6af62f1f5fae9" +checksum = "7dafe3a8757b027e2be6e4e5601ed563c55989fcf1546e933c66c8eb3a058d35" dependencies = [ - "anyhow", - "ark-bn254", - "ark-ec", - "ark-ff", - "ark-groth16", - "ark-serialize", - "bytemuck", - "hex", - "num-bigint", - "num-traits", - "risc0-binfmt", - "risc0-zkp", - "serde", + "bytes", + "either", ] [[package]] -name = "risc0-zkos-v1compat" -version = "2.2.0" +name = "bytestring" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "840c2228803557a8b7dc035a8f196516b6fd68c9dc6ac092f0c86241b5b1bafb" +checksum = "113b4343b5f6617e7ad401ced8de3cc8b012e73a594347c307b90db3e9271289" dependencies = [ - "include_bytes_aligned", - "no_std_strings", - "risc0-zkvm-platform", + "bytes", ] [[package]] -name = "risc0-zkp" -version = "3.0.2" +name = "c-kzg" +version = "2.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb6bf356f469bb8744f72a07a37134c5812c1d55d6271bba80e87bdb7a58c8e" +checksum = "e00bf4b112b07b505472dbefd19e37e53307e2bfed5a79e0cc161d58ccd0e687" dependencies = [ - "anyhow", - "blake2", - "borsh", - "bytemuck", - "cfg-if", - "digest", + "blst", + "cc", + "glob", "hex", - "hex-literal", - "metal", - "paste", - "rand_core 0.9.3", - "risc0-core", - "risc0-zkvm-platform", + "libc", + "once_cell", "serde", - "sha2", - "stability", - "tracing", ] [[package]] -name = "risc0-zkvm" -version = "3.0.3" +name = "calloop" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fcce11648a9ff60b8e7af2f0ce7fbf8d25275ab6d414cc91b9da69ee75bc978" +checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" dependencies = [ - "anyhow", - "bincode", - "bonsai-sdk", - "borsh", - "bytemuck", - "bytes", - "derive_more", - "hex", - "lazy-regex", - "prost", - "risc0-binfmt", - "risc0-build", - "risc0-circuit-keccak", - "risc0-circuit-recursion", - "risc0-circuit-rv32im", - "risc0-core", - "risc0-groth16", - "risc0-zkos-v1compat", - "risc0-zkp", - "risc0-zkvm-platform", - "rrs-lib", - "rzup", - "semver", - "serde", - "sha2", - "stability", - "tempfile", - "tracing", + "bitflags 2.10.0", + "log", + "polling", + "rustix 0.38.44", + "slab", + "thiserror 1.0.69", ] [[package]] -name = "risc0-zkvm-platform" -version = "2.2.1" +name = "camino" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfaa10feba15828c788837ddde84b994393936d8f5715228627cfe8625122a40" +checksum = "276a59bf2b2c967788139340c9f0c5b12d7fd6630315c15c217e559de85d2609" dependencies = [ - "bytemuck", - "cfg-if", - "getrandom 0.2.16", - "getrandom 0.3.4", - "libm", - "num_enum", - "paste", - "stability", + "serde_core", ] [[package]] -name = "ron" -version = "0.11.0" +name = "cargo-platform" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db09040cc89e461f1a265139777a2bde7f8d8c67c4936f700c63ce3e2904d468" +checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" dependencies = [ - "base64", - "bitflags 2.10.0", "serde", - "serde_derive", - "unicode-ident", ] [[package]] -name = "rrs-lib" -version = "0.1.0" +name = "cargo_metadata" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4382d3af3a4ebdae7f64ba6edd9114fff92c89808004c4943b393377a25d001" +checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" dependencies = [ - "downcast-rs", - "paste", + "camino", + "cargo-platform", + "semver 1.0.27", + "serde", + "serde_json", + "thiserror 1.0.69", ] [[package]] -name = "rsa" -version = "0.9.8" +name = "cargo_metadata" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78928ac1ed176a5ca1d17e578a1825f3d81ca54cf41053a592584b020cfd691b" +checksum = "dd5eb614ed4c27c5d706420e4320fbe3216ab31fa1c33cd8246ac36dae4479ba" dependencies = [ - "const-oid", - "digest", - "num-bigint-dig", - "num-integer", - "num-traits", - "pkcs1", - "pkcs8", - "rand_core 0.6.4", - "signature", - "spki", - "subtle", - "zeroize", + "camino", + "cargo-platform", + "semver 1.0.27", + "serde", + "serde_json", + "thiserror 2.0.17", ] [[package]] -name = "ruint" -version = "1.17.0" +name = "cassowary" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a68df0380e5c9d20ce49534f292a36a7514ae21350726efe1865bdb1fa91d278" +checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" + +[[package]] +name = "castaway" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dec551ab6e7578819132c713a93c022a05d60159dc86e7a7050223577484c55a" dependencies = [ - "borsh", - "proptest", - "rand 0.8.5", - "rand 0.9.2", - "ruint-macro", - "serde_core", - "valuable", - "zeroize", + "rustversion", ] [[package]] -name = "ruint-macro" -version = "1.2.1" +name = "cbc" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" +checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" +dependencies = [ + "cipher", +] [[package]] -name = "runtime" -version = "0.1.0" +name = "cbindgen" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fce8dd7fcfcbf3a0a87d8f515194b49d6135acab73e18bd380d1d93bb1a15eb" dependencies = [ - "async-trait", - "bincode", - "client-bootstrap", - "directories", - "game-content", - "game-core", - "memmap2", - "ron", + "clap", + "heck 0.4.1", + "indexmap 2.12.1", + "log", + "proc-macro2", + "quote", "serde", "serde_json", + "syn 2.0.110", "tempfile", - "thiserror 2.0.17", - "tokio", - "tracing", - "zk", + "toml 0.8.23", ] [[package]] -name = "rustc-hash" -version = "2.1.1" +name = "cc" +version = "1.2.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" +checksum = "cd405d82c84ff7f35739f175f67d8b9fb7687a0e84ccdc78bd3568839827cf07" +dependencies = [ + "find-msvc-tools", + "jobserver", + "libc", + "shlex", +] [[package]] -name = "rustix" -version = "0.38.44" +name = "cesu8" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" dependencies = [ - "bitflags 2.10.0", - "errno", - "libc", - "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", + "nom", ] [[package]] -name = "rustix" -version = "1.1.2" +name = "cfg-if" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "chrono" +version = "0.4.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" dependencies = [ - "bitflags 2.10.0", - "errno", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-link", +] + +[[package]] +name = "ciborium" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" + +[[package]] +name = "ciborium-ll" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +dependencies = [ + "ciborium-io", + "half", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", "libc", - "linux-raw-sys 0.11.0", - "windows-sys 0.61.2", + "libloading", ] [[package]] -name = "rustls" -version = "0.23.34" +name = "clap" +version = "4.5.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a9586e9ee2b4f8fab52a0048ca7334d7024eef48e2cb9407e3497bb7cab7fa7" +checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" dependencies = [ - "once_cell", - "ring", - "rustls-pki-types", - "rustls-webpki", - "subtle", - "zeroize", + "clap_builder", + "clap_derive", ] [[package]] -name = "rustls-pki-types" -version = "1.12.0" +name = "clap_builder" +version = "4.5.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" dependencies = [ - "web-time", - "zeroize", + "anstream", + "anstyle", + "clap_lex", + "strsim 0.11.1", + "terminal_size", ] [[package]] -name = "rustls-webpki" -version = "0.103.7" +name = "clap_derive" +version = "4.5.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10b3f4191e8a80e6b43eebabfac91e5dcecebb27a71f04e820c47ec41d314bf" +checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" dependencies = [ - "ring", - "rustls-pki-types", - "untrusted", + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "clap_lex" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" + +[[package]] +name = "client-blockchain-sui" +version = "0.1.0" +dependencies = [ + "anyhow", + "async-trait", + "bcs", + "bincode", + "dirs 5.0.1", + "hex", + "reqwest 0.11.27", + "serde", + "serde_json", + "shared-crypto", + "sp1-sdk", + "sp1-sui", + "sui-json-rpc-types", + "sui-keys", + "sui-sdk", + "sui-types", + "thiserror 2.0.17", + "tokio", + "toml 0.8.23", + "tracing", + "zk", +] + +[[package]] +name = "client-bootstrap" +version = "0.1.0" +dependencies = [ + "anyhow", + "game-content", + "game-core", + "runtime", + "tokio", + "tracing", +] + +[[package]] +name = "client-frontend-bevy" +version = "0.1.0" +dependencies = [ + "anyhow", + "async-trait", + "bevy", + "client-blockchain-sui", + "client-bootstrap", + "client-frontend-core", + "game-core", + "runtime", + "thiserror 2.0.17", + "tokio", + "tracing", +] + +[[package]] +name = "client-frontend-cli" +version = "0.1.0" +dependencies = [ + "anyhow", + "async-trait", + "client-blockchain-sui", + "client-bootstrap", + "client-frontend-core", + "crossterm 0.29.0", + "dotenvy", + "game-core", + "hex", + "ratatui", + "runtime", + "thiserror 2.0.17", + "tokio", + "tracing", + "tracing-appender", + "tracing-subscriber 0.3.20", +] + +[[package]] +name = "client-frontend-core" +version = "0.1.0" +dependencies = [ + "anyhow", + "arrayvec", + "async-trait", + "bitflags 2.10.0", + "game-core", + "runtime", +] + +[[package]] +name = "clipboard-win" +version = "5.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bde03770d3df201d4fb868f2c9c59e66a3e4e2bd06692a0fe701e7103c7e84d4" +dependencies = [ + "error-code", +] + +[[package]] +name = "cmake" +version = "0.1.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" +dependencies = [ + "cc", +] + +[[package]] +name = "cmp_any" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9b18233253483ce2f65329a24072ec414db782531bdbb7d0bbc4bd2ce6b7e21" + +[[package]] +name = "cobs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" +dependencies = [ + "thiserror 2.0.17", +] + +[[package]] +name = "codespan" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3362992a0d9f1dd7c3d0e89e0ab2bb540b7a95fea8cd798090e758fda2899b5e" +dependencies = [ + "codespan-reporting", + "serde", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "serde", + "termcolor", + "unicode-width 0.1.14", +] + +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + +[[package]] +name = "colored" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" +dependencies = [ + "lazy_static", + "windows-sys 0.59.0", +] + +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "compact_str" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b79c4069c6cad78e2e0cdfcbd26275770669fb39fd308a752dc110e83b9af32" +dependencies = [ + "castaway", + "cfg-if", + "itoa", + "rustversion", + "ryu", + "static_assertions", +] + +[[package]] +name = "compression-codecs" +version = "0.4.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "680dc087785c5230f8e8843e2e57ac7c1c90488b6a91b88caa265410568f441b" +dependencies = [ + "brotli", + "compression-core", + "flate2", + "memchr", + "zstd", + "zstd-safe", +] + +[[package]] +name = "compression-core" +version = "0.4.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a9b614a5787ef0c8802a55766480563cb3a93b435898c422ed2a359cf811582" + +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "consensus-config" +version = "0.1.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "fastcrypto", + "mysten-network", + "rand 0.8.5", + "serde", + "shared-crypto", +] + +[[package]] +name = "consensus-types" +version = "0.1.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "base64 0.21.7", + "consensus-config", + "fastcrypto", + "serde", +] + +[[package]] +name = "console" +version = "0.15.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" +dependencies = [ + "encode_unicode", + "libc", + "once_cell", + "unicode-width 0.2.0", + "windows-sys 0.59.0", +] + +[[package]] +name = "console" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b430743a6eb14e9764d4260d4c0d8123087d504eeb9c48f2b2a5e810dd369df4" +dependencies = [ + "encode_unicode", + "libc", + "once_cell", + "unicode-width 0.2.0", + "windows-sys 0.61.2", +] + +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + +[[package]] +name = "const-fnv1a-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b13ea120a812beba79e34316b3942a857c86ec1593cb34f27bb28272ce2cca" + +[[package]] +name = "const-hex" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bb320cac8a0750d7f25280aa97b09c26edfe161164238ecbbb31092b079e735" +dependencies = [ + "cfg-if", + "cpufeatures", + "proptest", + "serde_core", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "const-random" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" +dependencies = [ + "const-random-macro", +] + +[[package]] +name = "const-random-macro" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" +dependencies = [ + "getrandom 0.2.16", + "once_cell", + "tiny-keccak", +] + +[[package]] +name = "const-str" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f421161cb492475f1661ddc9815a745a1c894592070661180fdec3d4872e9c3" + +[[package]] +name = "const_format" +version = "0.2.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7faa7469a93a566e9ccc1c73fe783b4a65c274c5ace346038dca9c39fe0030ad" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "const_panic" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e262cdaac42494e3ae34c43969f9cdeb7da178bdb4b66fa6a1ea2edb4c8ae652" +dependencies = [ + "typewit", +] + +[[package]] +name = "const_soft_float" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ca1caa64ef4ed453e68bb3db612e51cf1b2f5b871337f0fcab1c8f87cc3dff" + +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + +[[package]] +name = "constgebra" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1aaf9b65849a68662ac6c0810c8893a765c960b907dd7cfab9c4a50bf764fbc" +dependencies = [ + "const_soft_float", +] + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "convert_case" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb402b8d4c85569410425650ce3eddc7d698ed96d39a73f941b08fb63082f1e7" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "core-graphics" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" +dependencies = [ + "bitflags 1.3.2", + "core-foundation 0.9.4", + "core-graphics-types", + "foreign-types 0.5.0", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" +dependencies = [ + "bitflags 1.3.2", + "core-foundation 0.9.4", + "libc", +] + +[[package]] +name = "core2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" +dependencies = [ + "memchr", +] + +[[package]] +name = "coset" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8cc80f631f8307b887faca24dcc3abc427cd0367f6eb6188f6e8f5b7ad8fb" +dependencies = [ + "ciborium", + "ciborium-io", +] + +[[package]] +name = "cosmic-text" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59fd57d82eb4bfe7ffa9b1cec0c05e2fd378155b47f255a67983cb4afe0e80c2" +dependencies = [ + "bitflags 2.10.0", + "fontdb", + "log", + "rangemap", + "rayon", + "rustc-hash 1.1.0", + "rustybuzz", + "self_cell", + "swash", + "sys-locale", + "ttf-parser 0.21.1", + "unicode-bidi", + "unicode-linebreak", + "unicode-script", + "unicode-segmentation", +] + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9710d3b3739c2e349eb44fe848ad0b7c8cb1e42bd87ee49371df2f7acaf3e675" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crossterm" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" +dependencies = [ + "bitflags 2.10.0", + "crossterm_winapi", + "mio", + "parking_lot", + "rustix 0.38.44", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b" +dependencies = [ + "bitflags 2.10.0", + "crossterm_winapi", + "derive_more 2.0.1", + "document-features", + "futures-core", + "mio", + "parking_lot", + "rustix 1.1.2", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +dependencies = [ + "winapi", +] + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "crypto-bigint" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +dependencies = [ + "generic-array 0.14.7", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array 0.14.7", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array 0.14.7", + "rand_core 0.6.4", + "typenum", +] + +[[package]] +name = "csv" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52cd9d68cf7efc6ddfaaee42e7288d3a99d613d4b50f76ce9827ae0c6e14f938" +dependencies = [ + "csv-core", + "itoa", + "ryu", + "serde_core", +] + +[[package]] +name = "csv-core" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "704a3c26996a80471189265814dbc2c257598b96b8a7feae2d31ace646bb9782" +dependencies = [ + "memchr", +] + +[[package]] +name = "ctor" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + +[[package]] +name = "ctrlc" +version = "3.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73736a89c4aff73035ba2ed2e565061954da00d4970fc9ac25dcc85a2a20d790" +dependencies = [ + "dispatch2", + "nix 0.30.1", + "windows-sys 0.61.2", +] + +[[package]] +name = "cursor-icon" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f" + +[[package]] +name = "curve25519-dalek-ng" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c359b7249347e46fb28804470d071c921156ad62b3eef5d34e2ba867533dec8" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.6.4", + "subtle-ng", + "zeroize", +] + +[[package]] +name = "darling" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +dependencies = [ + "darling_core 0.14.4", + "darling_macro 0.14.4", +] + +[[package]] +name = "darling" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +dependencies = [ + "darling_core 0.20.11", + "darling_macro 0.20.11", +] + +[[package]] +name = "darling" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" +dependencies = [ + "darling_core 0.21.3", + "darling_macro 0.21.3", +] + +[[package]] +name = "darling_core" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.10.0", + "syn 1.0.109", +] + +[[package]] +name = "darling_core" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.11.1", + "syn 2.0.110", +] + +[[package]] +name = "darling_core" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "serde", + "strsim 0.11.1", + "syn 2.0.110", +] + +[[package]] +name = "darling_macro" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +dependencies = [ + "darling_core 0.14.4", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "darling_macro" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +dependencies = [ + "darling_core 0.20.11", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "darling_macro" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" +dependencies = [ + "darling_core 0.21.3", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "dashu" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b3e5ac1e23ff1995ef05b912e2b012a8784506987a2651552db2c73fb3d7e0" +dependencies = [ + "dashu-base", + "dashu-float", + "dashu-int", + "dashu-macros", + "dashu-ratio", + "rustversion", +] + +[[package]] +name = "dashu-base" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0b80bf6b85aa68c58ffea2ddb040109943049ce3fbdf4385d0380aef08ef289" + +[[package]] +name = "dashu-float" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85078445a8dbd2e1bd21f04a816f352db8d333643f0c9b78ca7c3d1df71063e7" +dependencies = [ + "dashu-base", + "dashu-int", + "num-modular", + "num-order", + "rustversion", + "static_assertions", +] + +[[package]] +name = "dashu-int" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee99d08031ca34a4d044efbbb21dff9b8c54bb9d8c82a189187c0651ffdb9fbf" +dependencies = [ + "cfg-if", + "dashu-base", + "num-modular", + "num-order", + "rustversion", + "static_assertions", +] + +[[package]] +name = "dashu-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93381c3ef6366766f6e9ed9cf09e4ef9dec69499baf04f0c60e70d653cf0ab10" +dependencies = [ + "dashu-base", + "dashu-float", + "dashu-int", + "dashu-ratio", + "paste", + "proc-macro2", + "quote", + "rustversion", +] + +[[package]] +name = "dashu-ratio" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47e33b04dd7ce1ccf8a02a69d3419e354f2bbfdf4eb911a0b7465487248764c9" +dependencies = [ + "dashu-base", + "dashu-float", + "dashu-int", + "num-modular", + "num-order", + "rustversion", +] + +[[package]] +name = "data-encoding" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" + +[[package]] +name = "data-encoding-macro" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47ce6c96ea0102f01122a185683611bd5ac8d99e62bc59dd12e6bda344ee673d" +dependencies = [ + "data-encoding", + "data-encoding-macro-internal", +] + +[[package]] +name = "data-encoding-macro-internal" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d162beedaa69905488a8da94f5ac3edb4dd4788b732fadb7bd120b2625c1976" +dependencies = [ + "data-encoding", + "syn 2.0.110", +] + +[[package]] +name = "debugserver-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf6834a70ed14e8e4e41882df27190bea150f1f6ecf461f1033f8739cd8af4a" +dependencies = [ + "schemafy", + "serde", + "serde_json", +] + +[[package]] +name = "der" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +dependencies = [ + "const-oid", + "pem-rfc7468 0.6.0", + "zeroize", +] + +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid", + "pem-rfc7468 0.7.0", + "zeroize", +] + +[[package]] +name = "der-parser" +version = "10.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07da5016415d5a3c4dd39b11ed26f915f52fc4e0dc197d87908bc916e51bc1a6" +dependencies = [ + "asn1-rs", + "displaydoc", + "nom", + "num-bigint 0.4.6", + "num-traits", + "rusticata-macros", +] + +[[package]] +name = "deranged" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" +dependencies = [ + "powerfmt", + "serde_core", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive-syn-parse" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e79116f119dd1dba1abf1f3405f03b9b0e79a27a3883864bfebded8a3dc768cd" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_builder" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" +dependencies = [ + "darling 0.20.11", + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "derive_builder_macro" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" +dependencies = [ + "derive_builder_core", + "syn 2.0.110", +] + +[[package]] +name = "derive_more" +version = "0.99.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" +dependencies = [ + "convert_case 0.4.0", + "proc-macro2", + "quote", + "rustc_version 0.4.1", + "syn 2.0.110", +] + +[[package]] +name = "derive_more" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" +dependencies = [ + "derive_more-impl 1.0.0", +] + +[[package]] +name = "derive_more" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" +dependencies = [ + "derive_more-impl 2.0.1", +] + +[[package]] +name = "derive_more-impl" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" +dependencies = [ + "convert_case 0.6.0", + "proc-macro2", + "quote", + "syn 2.0.110", + "unicode-xid", +] + +[[package]] +name = "derive_more-impl" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" +dependencies = [ + "convert_case 0.7.1", + "proc-macro2", + "quote", + "syn 2.0.110", + "unicode-xid", +] + +[[package]] +name = "diff" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" + +[[package]] +name = "difflib" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "directories" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16f5094c54661b38d03bd7e50df373292118db60b585c08a411c6d840017fe7d" +dependencies = [ + "dirs-sys 0.5.0", +] + +[[package]] +name = "dirs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +dependencies = [ + "dirs-sys 0.3.7", +] + +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys 0.4.1", +] + +[[package]] +name = "dirs" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" +dependencies = [ + "dirs-sys 0.5.0", +] + +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users 0.4.6", + "winapi", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users 0.4.6", + "windows-sys 0.48.0", +] + +[[package]] +name = "dirs-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" +dependencies = [ + "libc", + "option-ext", + "redox_users 0.5.2", + "windows-sys 0.61.2", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users 0.4.6", + "winapi", +] + +[[package]] +name = "dispatch" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" + +[[package]] +name = "dispatch2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" +dependencies = [ + "bitflags 2.10.0", + "block2 0.6.2", + "libc", + "objc2 0.6.3", +] + +[[package]] +name = "display_container" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a110a75c96bedec8e65823dea00a1d710288b7a369d95fd8a0f5127639466fa" +dependencies = [ + "either", + "indenter", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "disqualified" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9c272297e804878a2a4b707cfcfc6d2328b5bb936944613b4fdf2b9269afdfd" + +[[package]] +name = "dlib" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" +dependencies = [ + "libloading", +] + +[[package]] +name = "docker-generate" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf673e0848ef09fa4aeeba78e681cf651c0c7d35f76ee38cec8e55bc32fa111" + +[[package]] +name = "document-features" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" +dependencies = [ + "litrs", +] + +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + +[[package]] +name = "downcast" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" + +[[package]] +name = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + +[[package]] +name = "downloader" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ac1e888d6830712d565b2f3a974be3200be9296bc1b03db8251a4cbf18a4a34" +dependencies = [ + "digest 0.10.7", + "futures", + "rand 0.8.5", + "reqwest 0.12.24", + "thiserror 1.0.69", + "tokio", +] + +[[package]] +name = "dpi" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" + +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + +[[package]] +name = "dungeon-client" +version = "0.1.0" +dependencies = [ + "anyhow", + "async-trait", + "client-blockchain-sui", + "client-bootstrap", + "client-frontend-bevy", + "client-frontend-cli", + "client-frontend-core", + "dotenvy", + "runtime", + "tokio", + "tracing", + "tracing-subscriber 0.3.20", + "zk", +] + +[[package]] +name = "dupe" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed2bc011db9c93fbc2b6cdb341a53737a55bafb46dbb74cf6764fc33a2fbf9c" +dependencies = [ + "dupe_derive", +] + +[[package]] +name = "dupe_derive" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83e195b4945e88836d826124af44fdcb262ec01ef94d44f14f4fb5103f19892a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "duplicate" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e92f10a49176cbffacaedabfaa11d51db1ea0f80a83c26e1873b43cd1742c24" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "proc-macro2-diagnostics", +] + +[[package]] +name = "dyn-clone" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" + +[[package]] +name = "ecdsa" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +dependencies = [ + "der 0.6.1", + "elliptic-curve 0.12.3", + "rfc6979 0.3.1", + "signature 1.6.4", +] + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der 0.7.10", + "digest 0.10.7", + "elliptic-curve 0.13.8", + "rfc6979 0.4.0", + "serdect", + "signature 2.2.0", + "spki 0.7.3", +] + +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8 0.10.2", + "signature 2.2.0", + "zeroize", +] + +[[package]] +name = "ed25519-consensus" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c8465edc8ee7436ffea81d21a019b16676ee3db267aa8d5a8d729581ecf998b" +dependencies = [ + "curve25519-dalek-ng", + "hex", + "rand_core 0.6.4", + "serde", + "sha2 0.9.9", + "thiserror 1.0.69", + "zeroize", +] + +[[package]] +name = "educe" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7bc049e1bd8cdeb31b68bbd586a9464ecf9f3944af3958a7a9d0f8b9799417" +dependencies = [ + "enum-ordinalize", + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +dependencies = [ + "serde", +] + +[[package]] +name = "elf" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4445909572dbd556c457c849c4ca58623d84b27c8fff1e74b0b4227d8b90d17b" + +[[package]] +name = "elliptic-curve" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +dependencies = [ + "base16ct 0.1.1", + "crypto-bigint 0.4.9", + "der 0.6.1", + "digest 0.10.7", + "ff 0.12.1", + "generic-array 0.14.7", + "group 0.12.1", + "rand_core 0.6.4", + "sec1 0.3.0", + "subtle", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct 0.2.0", + "crypto-bigint 0.5.5", + "digest 0.10.7", + "ff 0.13.1", + "generic-array 0.14.7", + "group 0.13.0", + "hkdf", + "pem-rfc7468 0.7.0", + "pkcs8 0.10.2", + "rand_core 0.6.4", + "sec1 0.7.3", + "serdect", + "subtle", + "zeroize", +] + +[[package]] +name = "embedded-io" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" + +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" + +[[package]] +name = "ena" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d248bdd43ce613d87415282f69b9bb99d947d290b10962dd6c56233312c2ad5" +dependencies = [ + "log", +] + +[[package]] +name = "encase" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0a05902cf601ed11d564128448097b98ebe3c6574bd7b6a653a3d56d54aa020" +dependencies = [ + "const_panic", + "encase_derive", + "glam", + "thiserror 1.0.69", +] + +[[package]] +name = "encase_derive" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "181d475b694e2dd56ae919ce7699d344d1fd259292d590c723a50d1189a2ea85" +dependencies = [ + "encase_derive_impl", +] + +[[package]] +name = "encase_derive_impl" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f97b51c5cc57ef7c5f7a0c57c250251c49ee4c28f819f87ac32f4aceabc36792" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "encode_unicode" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "endian-type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" + +[[package]] +name = "enum-compat-util" +version = "0.1.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "serde_yaml", +] + +[[package]] +name = "enum-map" +version = "2.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6866f3bfdf8207509a033af1a75a7b08abda06bbaaeae6669323fd5a097df2e9" +dependencies = [ + "enum-map-derive", + "serde", +] + +[[package]] +name = "enum-map-derive" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "enum-ordinalize" +version = "4.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a1091a7bb1f8f2c4b28f1fe2cef4980ca2d410a3d727d67ecc3178c9b0800f0" +dependencies = [ + "enum-ordinalize-derive", +] + +[[package]] +name = "enum-ordinalize-derive" +version = "4.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ca9601fb2d62598ee17836250842873a413586e5d7ed88b356e38ddbb0ec631" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "enum_dispatch" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa18ce2bc66555b3218614519ac839ddb759a7d6720732f979ef8d13be147ecd" +dependencies = [ + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "erased-discriminant" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1a6df962265a53221f29081896c412ef325c17fa7d638cd9578febe53d3c82c" +dependencies = [ + "typeid", +] + +[[package]] +name = "erased-serde" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c" +dependencies = [ + "serde", +] + +[[package]] +name = "erased-serde" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89e8918065695684b2b0702da20382d5ae6065cf3327bc2d6436bd49a71ce9f3" +dependencies = [ + "serde", + "serde_core", + "typeid", +] + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "error-code" +version = "3.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59" + +[[package]] +name = "ethnum" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca81e6b4777c89fd810c25a4be2b1bd93ea034fbe58e6a75216a34c6b82c539b" + +[[package]] +name = "euclid" +version = "0.22.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad9cdb4b747e485a12abb0e6566612956c7a1bafa3bdb8d682c5b6d403589e48" +dependencies = [ + "num-traits", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "event-listener" +version = "5.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" +dependencies = [ + "event-listener 5.4.1", + "pin-project-lite", +] + +[[package]] +name = "eventsource-stream" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74fef4569247a5f429d9156b9d0a2599914385dd189c539334c625d8099d90ab" +dependencies = [ + "futures-core", + "nom", + "pin-project-lite", +] + +[[package]] +name = "eyre" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "fastbloom" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18c1ddb9231d8554c2d6bdf4cfaabf0c59251658c68b6c95cd52dd0c513a912a" +dependencies = [ + "getrandom 0.3.4", + "libm", + "rand 0.9.2", + "siphasher", +] + +[[package]] +name = "fastcrypto" +version = "0.1.9" +source = "git+https://github.com/MystenLabs/fastcrypto?rev=09f86974195ec85d8aae386b1909d341d3ccfe52#09f86974195ec85d8aae386b1909d341d3ccfe52" +dependencies = [ + "aes", + "aes-gcm", + "aes-gcm-siv", + "ark-ec 0.4.2", + "ark-ff 0.4.2", + "ark-secp256k1", + "ark-secp256r1", + "ark-serialize 0.4.2", + "auto_ops", + "base64ct", + "bcs", + "bech32", + "bincode", + "blake2", + "blst", + "bs58 0.4.0", + "cbc", + "ctr", + "curve25519-dalek-ng", + "derive_more 0.99.20", + "digest 0.10.7", + "ecdsa 0.16.9", + "ed25519-consensus", + "elliptic-curve 0.13.8", + "fastcrypto-derive", + "generic-array 0.14.7", + "hex", + "hex-literal", + "hkdf", + "lazy_static", + "num-bigint 0.4.6", + "once_cell", + "p256", + "rand 0.8.5", + "readonly", + "rfc6979 0.4.0", + "rsa 0.8.2", + "schemars 0.8.22", + "secp256k1 0.27.0", + "serde", + "serde_json", + "serde_with", + "sha2 0.10.9", + "sha3", + "signature 2.2.0", + "static_assertions", + "thiserror 1.0.69", + "tokio", + "typenum", + "zeroize", +] + +[[package]] +name = "fastcrypto-derive" +version = "0.1.3" +source = "git+https://github.com/MystenLabs/fastcrypto?rev=09f86974195ec85d8aae386b1909d341d3ccfe52#09f86974195ec85d8aae386b1909d341d3ccfe52" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "fastcrypto-tbls" +version = "0.1.0" +source = "git+https://github.com/MystenLabs/fastcrypto?rev=09f86974195ec85d8aae386b1909d341d3ccfe52#09f86974195ec85d8aae386b1909d341d3ccfe52" +dependencies = [ + "bcs", + "digest 0.10.7", + "fastcrypto", + "hex", + "itertools 0.10.5", + "rand 0.8.5", + "serde", + "serde-big-array", + "sha3", + "tap", + "tracing", + "typenum", + "zeroize", +] + +[[package]] +name = "fastcrypto-zkp" +version = "0.1.3" +source = "git+https://github.com/MystenLabs/fastcrypto?rev=09f86974195ec85d8aae386b1909d341d3ccfe52#09f86974195ec85d8aae386b1909d341d3ccfe52" +dependencies = [ + "ark-bn254 0.4.0", + "ark-ec 0.4.2", + "ark-ff 0.4.2", + "ark-groth16 0.4.0", + "ark-relations 0.4.0", + "ark-serialize 0.4.2", + "ark-snark 0.4.0", + "bcs", + "byte-slice-cast", + "derive_more 0.99.20", + "fastcrypto", + "ff 0.13.1", + "im", + "itertools 0.12.1", + "lazy_static", + "neptune", + "num-bigint 0.4.6", + "once_cell", + "regex", + "reqwest 0.12.24", + "schemars 0.8.22", + "serde", + "serde_json", + "typenum", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "fastrlp" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139834ddba373bbdd213dffe02c8d110508dcf1726c2be27e8d1f7d7e1856418" +dependencies = [ + "arrayvec", + "auto_impl", + "bytes", +] + +[[package]] +name = "fastrlp" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce8dba4714ef14b8274c371879b175aa55b16b30f269663f19d576f380018dc4" +dependencies = [ + "arrayvec", + "auto_impl", + "bytes", +] + +[[package]] +name = "fd-lock" +version = "4.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce92ff622d6dadf7349484f42c93271a0d49b7cc4d466a936405bacbe10aa78" +dependencies = [ + "cfg-if", + "rustix 1.1.2", + "windows-sys 0.59.0", +] + +[[package]] +name = "fdeflate" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "bitvec 1.0.1", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "ff" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +dependencies = [ + "bitvec 1.0.1", + "byteorder", + "ff_derive", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "ff_derive" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f10d12652036b0e99197587c6ba87a8fc3031986499973c030d8b44fcc151b60" +dependencies = [ + "addchain", + "num-bigint 0.3.3", + "num-integer", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" + +[[package]] +name = "fixed-hash" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c" +dependencies = [ + "byteorder", + "rand 0.8.5", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "fixed-hash" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" +dependencies = [ + "byteorder", + "rand 0.8.5", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "fixedbitset" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" + +[[package]] +name = "flate2" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "float-cmp" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" +dependencies = [ + "num-traits", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "font-types" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3971f9a5ca983419cdc386941ba3b9e1feba01a0ab888adf78739feb2798492" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "fontconfig-parser" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbc773e24e02d4ddd8395fd30dc147524273a83e54e0f312d986ea30de5f5646" +dependencies = [ + "roxmltree", +] + +[[package]] +name = "fontdb" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0299020c3ef3f60f526a4f64ab4a3d4ce116b1acbf24cdd22da0068e5d81dc3" +dependencies = [ + "fontconfig-parser", + "log", + "memmap2", + "slotmap", + "tinyvec", + "ttf-parser 0.20.0", +] + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared 0.1.1", +] + +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared 0.3.1", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "fragile" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dd6caf6059519a65843af8fe2a3ae298b14b80179855aeb4adc2c1934ee619" + +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + +[[package]] +name = "funty" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-lite" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "futures-utils-wasm" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42012b0f064e01aa58b545fe3727f90f7dd4020f4a3ea735b50344965f5a57e9" + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "game-content" +version = "0.1.0" +dependencies = [ + "anyhow", + "game-core", + "ron 0.11.0", + "serde", + "toml 0.9.8", +] + +[[package]] +name = "game-core" +version = "0.1.0" +dependencies = [ + "arrayvec", + "bincode", + "bitflags 2.10.0", + "bounded-vector", + "hex", + "serde", + "sha2 0.10.9", + "strum 0.26.3", + "thiserror 2.0.17", +] + +[[package]] +name = "gcd" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a" + +[[package]] +name = "gen_ops" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "304de19db7028420975a296ab0fcbbc8e69438c4ed254a1e41e2a7f37d5f0e0a" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "serde", + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "generic-array" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96512db27971c2c3eece70a1e106fbe6c87760234e31e8f7e5634912fe52794a" +dependencies = [ + "serde", + "typenum", +] + +[[package]] +name = "gethostname" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8" +dependencies = [ + "rustix 1.1.2", + "windows-link", +] + +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "r-efi", + "wasip2", + "wasm-bindgen", +] + +[[package]] +name = "ghash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" +dependencies = [ + "opaque-debug", + "polyval", +] + +[[package]] +name = "gimli" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" + +[[package]] +name = "gl_generator" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" +dependencies = [ + "khronos_api", + "log", + "xml-rs", +] + +[[package]] +name = "glam" +version = "0.29.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8babf46d4c1c9d92deac9f7be466f76dfc4482b6452fc5024b5e8daf6ffeb3ee" +dependencies = [ + "bytemuck", + "rand 0.8.5", + "serde", +] + +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + +[[package]] +name = "glow" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d51fa363f025f5c111e03f13eda21162faeacb6911fe8caa0c0349f9cf0c4483" +dependencies = [ + "js-sys", + "slotmap", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "glutin_wgl_sys" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c4ee00b289aba7a9e5306d57c2d05499b2e5dc427f84ac708bd2c090212cf3e" +dependencies = [ + "gl_generator", +] + +[[package]] +name = "governor" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68a7f542ee6b35af73b06abc0dad1c1bae89964e4e253bc4b587b91c9637867b" +dependencies = [ + "cfg-if", + "dashmap", + "futures", + "futures-timer", + "no-std-compat", + "nonzero_ext", + "parking_lot", + "portable-atomic", + "quanta", + "rand 0.8.5", + "smallvec", + "spinning_top", +] + +[[package]] +name = "gpu-alloc" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" +dependencies = [ + "bitflags 2.10.0", + "gpu-alloc-types", +] + +[[package]] +name = "gpu-alloc-types" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4" +dependencies = [ + "bitflags 2.10.0", +] + +[[package]] +name = "gpu-allocator" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c151a2a5ef800297b4e79efa4f4bec035c5f51d5ae587287c9b952bdf734cacd" +dependencies = [ + "log", + "presser", + "thiserror 1.0.69", + "windows 0.58.0", +] + +[[package]] +name = "gpu-descriptor" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b89c83349105e3732062a895becfc71a8f921bb71ecbbdd8ff99263e3b53a0ca" +dependencies = [ + "bitflags 2.10.0", + "gpu-descriptor-types", + "hashbrown 0.15.5", +] + +[[package]] +name = "gpu-descriptor-types" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91" +dependencies = [ + "bitflags 2.10.0", +] + +[[package]] +name = "grid" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be136d9dacc2a13cc70bb6c8f902b414fb2641f8db1314637c6b7933411a8f82" + +[[package]] +name = "group" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff 0.12.1", + "memuse", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff 0.13.1", + "rand 0.8.5", + "rand_core 0.6.4", + "rand_xorshift 0.3.0", + "subtle", +] + +[[package]] +name = "guillotiere" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62d5865c036cb1393e23c50693df631d3f5d7bcca4c04fe4cc0fd592e74a782" +dependencies = [ + "euclid", + "svg_fmt", +] + +[[package]] +name = "h2" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0beca50380b1fc32983fc1cb4587bfa4bb9e78fc259aad4a0032d2080309222d" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.12", + "indexmap 2.12.1", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "h2" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http 1.3.1", + "indexmap 2.12.1", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "half" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" +dependencies = [ + "cfg-if", + "crunchy", + "zerocopy", +] + +[[package]] +name = "halo2" +version = "0.1.0-beta.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a23c779b38253fe1538102da44ad5bd5378495a61d2c4ee18d64eaa61ae5995" +dependencies = [ + "halo2_proofs", +] + +[[package]] +name = "halo2_proofs" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e925780549adee8364c7f2b685c753f6f3df23bde520c67416e93bf615933760" +dependencies = [ + "blake2b_simd", + "ff 0.12.1", + "group 0.12.1", + "pasta_curves 0.4.1", + "rand_core 0.6.4", + "rayon", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", + "serde", +] + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash 0.1.5", +] + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +dependencies = [ + "foldhash 0.2.0", + "serde", + "serde_core", +] + +[[package]] +name = "hashlink" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" +dependencies = [ + "hashbrown 0.15.5", +] + +[[package]] +name = "hdrhistogram" +version = "7.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "765c9198f173dd59ce26ff9f95ef0aafd0a0fe01fb9d72841bc5066a4c06511d" +dependencies = [ + "byteorder", + "num-traits", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +dependencies = [ + "serde", +] + +[[package]] +name = "hex-conservative" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5313b072ce3c597065a808dbf612c4c8e8590bdbf8b579508bf7a762c5eae6cd" +dependencies = [ + "arrayvec", +] + +[[package]] +name = "hex-literal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + +[[package]] +name = "hexasphere" +version = "15.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c9e718d32b6e6b2b32354e1b0367025efdd0b11d6a740b905ddf5db1074679" +dependencies = [ + "constgebra", + "glam", + "tinyvec", +] + +[[package]] +name = "hexf-parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "hmac-sha512" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77e806677ce663d0a199541030c816847b36e8dc095f70dae4a4f4ad63da5383" + +[[package]] +name = "home" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http 0.2.12", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http 1.3.1", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http 1.3.1", + "http-body 1.0.1", + "pin-project-lite", +] + +[[package]] +name = "http-range-header" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9171a2ea8a68358193d15dd5d70c1c10a2afc3e7e4c5bc92bc9f025cebd7359c" + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "humantime" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" + +[[package]] +name = "hyper" +version = "0.14.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2 0.3.27", + "http 0.2.12", + "http-body 0.4.6", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.5.10", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "h2 0.4.12", + "http 1.3.1", + "http-body 1.0.1", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "pin-utils", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http 0.2.12", + "hyper 0.14.32", + "log", + "rustls 0.21.12", + "rustls-native-certs 0.6.3", + "tokio", + "tokio-rustls 0.24.1", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +dependencies = [ + "http 1.3.1", + "hyper 1.8.1", + "hyper-util", + "log", + "rustls 0.23.35", + "rustls-native-certs 0.8.2", + "rustls-pki-types", + "tokio", + "tokio-rustls 0.26.4", + "tower-service", + "webpki-roots", +] + +[[package]] +name = "hyper-timeout" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" +dependencies = [ + "hyper 1.8.1", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper 0.14.32", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "hyper-util" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e9a2a24dc5c6821e71a7030e1e14b7b632acac55c40e9d2e082c621261bb56" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http 1.3.1", + "http-body 1.0.1", + "hyper 1.8.1", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2 0.6.1", + "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core 0.62.2", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "icu_collections" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" + +[[package]] +name = "icu_properties" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99" +dependencies = [ + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899" + +[[package]] +name = "icu_provider" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "im" +version = "15.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0acd33ff0285af998aaf9b57342af478078f53492322fafc47450e09397e0e9" +dependencies = [ + "bitmaps", + "rand_core 0.6.4", + "rand_xoshiro", + "sized-chunks", + "typenum", + "version_check", +] + +[[package]] +name = "image" +version = "0.25.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6506c6c10786659413faa717ceebcb8f70731c0a60cbae39795fdf114519c1a" +dependencies = [ + "bytemuck", + "byteorder-lite", + "moxcms", + "num-traits", + "png", +] + +[[package]] +name = "immutable-chunkmap" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3e98b1520e49e252237edc238a39869da9f3241f2ec19dc788c1d24694d1e4" +dependencies = [ + "arrayvec", +] + +[[package]] +name = "impl-codec" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "161ebdfec3c8e3b52bf61c4f3550a1eea4f9579d10dc1b936f3171ebdcd6c443" +dependencies = [ + "parity-scale-codec 2.3.1", +] + +[[package]] +name = "impl-codec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +dependencies = [ + "parity-scale-codec 3.7.5", +] + +[[package]] +name = "impl-serde" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4551f042f3438e64dbd6226b20527fc84a6e1fe65688b58746a2f53623f25f5c" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "include_bytes_aligned" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ee796ad498c8d9a1d68e477df8f754ed784ef875de1414ebdaf169f70a6a784" + +[[package]] +name = "indenter" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" +dependencies = [ + "equivalent", + "hashbrown 0.16.1", + "serde", + "serde_core", +] + +[[package]] +name = "indicatif" +version = "0.17.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "183b3088984b400f4cfac3620d5e076c84da5364016b4f49473de574b2586235" +dependencies = [ + "console 0.15.11", + "number_prefix", + "portable-atomic", + "unicode-width 0.2.0", + "web-time", +] + +[[package]] +name = "indoc" +version = "2.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706" +dependencies = [ + "rustversion", +] + +[[package]] +name = "inline_colorization" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1804bdb6a9784758b200007273a8b84e2b0b0b97a8f1e18e763eceb3e9f98a" + +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "block-padding", + "generic-array 0.14.7", +] + +[[package]] +name = "insta" +version = "1.44.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8732d3774162a0851e3f2b150eb98f31a9885dd75985099421d393385a01dfd" +dependencies = [ + "console 0.15.11", + "once_cell", + "serde", + "similar", +] + +[[package]] +name = "instability" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435d80800b936787d62688c927b6490e887c7ef5ff9ce922c6c6050fca75eb9a" +dependencies = [ + "darling 0.20.11", + "indoc", + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "inventory" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc61209c082fbeb19919bee74b176221b27223e27b65d781eb91af24eb1fb46e" +dependencies = [ + "rustversion", +] + +[[package]] +name = "ipnet" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + +[[package]] +name = "iri-string" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f867b9d1d896b67beb18518eda36fdb77a32ea590de864f1325b294a6d14397" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "is-terminal" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys", + "log", + "thiserror 1.0.69", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "jobserver" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +dependencies = [ + "getrandom 0.3.4", + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b011eec8cc36da2aab2d5cff675ec18454fad408585853910a202391cf9f8e65" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "json_to_table" +version = "0.6.0" +source = "git+https://github.com/zhiburt/tabled/?rev=e449317a1c02eb6b29e409ad6617e5d9eb7b3bd4#e449317a1c02eb6b29e409ad6617e5d9eb7b3bd4" +dependencies = [ + "serde_json", + "tabled", +] + +[[package]] +name = "jsonrpc" +version = "0.1.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "serde", + "serde_json", + "thiserror 1.0.69", + "tokio", + "tracing", +] + +[[package]] +name = "jsonrpsee" +version = "0.24.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e281ae70cc3b98dac15fced3366a880949e65fc66e345ce857a5682d152f3e62" +dependencies = [ + "jsonrpsee-core", + "jsonrpsee-http-client", + "jsonrpsee-proc-macros", + "jsonrpsee-server", + "jsonrpsee-types", + "jsonrpsee-ws-client", + "tokio", + "tracing", +] + +[[package]] +name = "jsonrpsee-client-transport" +version = "0.24.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc4280b709ac3bb5e16cf3bad5056a0ec8df55fa89edfe996361219aadc2c7ea" +dependencies = [ + "base64 0.22.1", + "futures-util", + "http 1.3.1", + "jsonrpsee-core", + "pin-project", + "rustls 0.23.35", + "rustls-pki-types", + "rustls-platform-verifier", + "soketto", + "thiserror 1.0.69", + "tokio", + "tokio-rustls 0.26.4", + "tokio-util", + "tracing", + "url", +] + +[[package]] +name = "jsonrpsee-core" +version = "0.24.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "348ee569eaed52926b5e740aae20863762b16596476e943c9e415a6479021622" +dependencies = [ + "async-trait", + "bytes", + "futures-timer", + "futures-util", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "jsonrpsee-types", + "parking_lot", + "pin-project", + "rand 0.8.5", + "rustc-hash 2.1.1", + "serde", + "serde_json", + "thiserror 1.0.69", + "tokio", + "tokio-stream", + "tracing", +] + +[[package]] +name = "jsonrpsee-http-client" +version = "0.24.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f50c389d6e6a52eb7c3548a6600c90cf74d9b71cb5912209833f00a5479e9a01" +dependencies = [ + "async-trait", + "base64 0.22.1", + "http-body 1.0.1", + "hyper 1.8.1", + "hyper-rustls 0.27.7", + "hyper-util", + "jsonrpsee-core", + "jsonrpsee-types", + "rustls 0.23.35", + "rustls-platform-verifier", + "serde", + "serde_json", + "thiserror 1.0.69", + "tokio", + "tower 0.4.13", + "tracing", + "url", +] + +[[package]] +name = "jsonrpsee-proc-macros" +version = "0.24.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7398cddf5013cca4702862a2692b66c48a3bd6cf6ec681a47453c93d63cf8de5" +dependencies = [ + "heck 0.5.0", + "proc-macro-crate 3.4.0", + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "jsonrpsee-server" +version = "0.24.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21429bcdda37dcf2d43b68621b994adede0e28061f816b038b0f18c70c143d51" +dependencies = [ + "futures-util", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "hyper 1.8.1", + "hyper-util", + "jsonrpsee-core", + "jsonrpsee-types", + "pin-project", + "route-recognizer", + "serde", + "serde_json", + "soketto", + "thiserror 1.0.69", + "tokio", + "tokio-stream", + "tokio-util", + "tower 0.4.13", + "tracing", +] + +[[package]] +name = "jsonrpsee-types" +version = "0.24.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0f05e0028e55b15dbd2107163b3c744cd3bb4474f193f95d9708acbf5677e44" +dependencies = [ + "http 1.3.1", + "serde", + "serde_json", + "thiserror 1.0.69", +] + +[[package]] +name = "jsonrpsee-ws-client" +version = "0.24.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78fc744f17e7926d57f478cf9ca6e1ee5d8332bf0514860b1a3cdf1742e614cc" +dependencies = [ + "http 1.3.1", + "jsonrpsee-client-transport", + "jsonrpsee-core", + "jsonrpsee-types", + "url", +] + +[[package]] +name = "jubjub" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a575df5f985fe1cd5b2b05664ff6accfc46559032b954529fd225a2168d27b0f" +dependencies = [ + "bitvec 1.0.1", + "bls12_381", + "ff 0.12.1", + "group 0.12.1", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "k256" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +dependencies = [ + "cfg-if", + "ecdsa 0.14.8", + "elliptic-curve 0.12.3", + "sha2 0.10.9", + "sha3", +] + +[[package]] +name = "k256" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" +dependencies = [ + "cfg-if", + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", + "once_cell", + "serdect", + "sha2 0.10.9", + "signature 2.2.0", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "keccak-asm" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "505d1856a39b200489082f90d897c3f07c455563880bc5952e38eabf731c83b6" +dependencies = [ + "digest 0.10.7", + "sha3-asm", +] + +[[package]] +name = "khronos-egl" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76" +dependencies = [ + "libc", + "libloading", + "pkg-config", +] + +[[package]] +name = "khronos_api" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" + +[[package]] +name = "lalrpop" +version = "0.19.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a1cbf952127589f2851ab2046af368fd20645491bb4b376f04b7f94d7a9837b" +dependencies = [ + "ascii-canvas", + "bit-set 0.5.3", + "diff", + "ena", + "is-terminal", + "itertools 0.10.5", + "lalrpop-util", + "petgraph 0.6.5", + "regex", + "regex-syntax 0.6.29", + "string_cache", + "term", + "tiny-keccak", + "unicode-xid", +] + +[[package]] +name = "lalrpop-util" +version = "0.19.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3c48237b9604c5a4702de6b824e02006c3214327564636aef27c1028a8fa0ed" +dependencies = [ + "regex", +] + +[[package]] +name = "lazy-regex" +version = "3.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "191898e17ddee19e60bccb3945aa02339e81edd4a8c50e21fd4d48cdecda7b29" +dependencies = [ + "lazy-regex-proc_macros", + "once_cell", + "regex", +] + +[[package]] +name = "lazy-regex-proc_macros" +version = "3.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c35dc8b0da83d1a9507e12122c80dea71a9c7c613014347392483a83ea593e04" +dependencies = [ + "proc-macro2", + "quote", + "regex", + "syn 2.0.110", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +dependencies = [ + "spin", +] + +[[package]] +name = "lcov" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ccfa6d5e585a884db65b37f38184e4364eaf74d884ac35d0a90fe9baf80b723" +dependencies = [ + "thiserror 1.0.69", +] + +[[package]] +name = "leb128" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" + +[[package]] +name = "libc" +version = "0.2.177" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" + +[[package]] +name = "libloading" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" +dependencies = [ + "cfg-if", + "windows-link", +] + +[[package]] +name = "libm" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" + +[[package]] +name = "libredox" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" +dependencies = [ + "bitflags 2.10.0", + "libc", + "redox_syscall 0.5.18", +] + +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[package]] +name = "linkme" +version = "0.3.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e3283ed2d0e50c06dd8602e0ab319bb048b6325d0bba739db64ed8205179898" +dependencies = [ + "linkme-impl", +] + +[[package]] +name = "linkme-impl" +version = "0.3.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5cec0ec4228b4853bb129c84dbf093a27e6c7a20526da046defc334a1b017f7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + +[[package]] +name = "linux-raw-sys" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" + +[[package]] +name = "litemap" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" + +[[package]] +name = "litrs" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" +dependencies = [ + "serde", +] + +[[package]] +name = "logos" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf8b031682c67a8e3d5446840f9573eb7fe26efe7ec8d195c9ac4c0647c502f1" +dependencies = [ + "logos-derive", +] + +[[package]] +name = "logos-derive" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d849148dbaf9661a6151d1ca82b13bb4c4c128146a88d05253b38d4e2f496c" +dependencies = [ + "beef", + "fnv", + "proc-macro2", + "quote", + "regex-syntax 0.6.29", + "syn 1.0.109", +] + +[[package]] +name = "lru" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "718e8fae447df0c7e1ba7f5189829e63fd536945c8988d61444c19039f16b670" +dependencies = [ + "hashbrown 0.13.2", +] + +[[package]] +name = "lru" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" +dependencies = [ + "hashbrown 0.15.5", +] + +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + +[[package]] +name = "lsp-types" +version = "0.94.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c66bfd44a06ae10647fe3f8214762e9369fd4248df1350924b4ef9e770a85ea1" +dependencies = [ + "bitflags 1.3.2", + "serde", + "serde_json", + "serde_repr", + "url", +] + +[[package]] +name = "lsp-types" +version = "0.95.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e34d33a8e9b006cd3fc4fe69a921affa097bae4bb65f76271f4644f9a334365" +dependencies = [ + "bitflags 1.3.2", + "serde", + "serde_json", + "serde_repr", + "url", +] + +[[package]] +name = "macro-string" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b27834086c65ec3f9387b096d66e99f221cf081c2b738042aa252bcd41204e3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "maplit" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" + +[[package]] +name = "match-lookup" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1265724d8cb29dbbc2b0f06fffb8bf1a8c0cf73a78eede9ba73a4a66c52a981e" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "matchers" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "matchit" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73cbba799671b762df5a175adf59ce145165747bb891505c43d09aefbbf38beb" + +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + +[[package]] +name = "matchit" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" + +[[package]] +name = "maybe-async" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cf92c10c7e361d6b99666ec1c6f9805b0bea2c3bd8c78dc6fe98ac5bd78db11" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest 0.10.7", +] + +[[package]] +name = "memchr" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" + +[[package]] +name = "memmap2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "744133e4a0e0a658e1374cf3bf8e415c4052a15a111acd372764c55b4177d490" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "memuse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d97bbf43eb4f088f8ca469930cde17fa036207c9a5e02ccc5107c4e8b17c964" + +[[package]] +name = "merlin" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d" +dependencies = [ + "byteorder", + "keccak", + "rand_core 0.6.4", + "zeroize", +] + +[[package]] +name = "metal" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ecfd3296f8c56b7c1f6fbac3c71cefa9d78ce009850c45000015f206dc7fa21" +dependencies = [ + "bitflags 2.10.0", + "block", + "core-graphics-types", + "foreign-types 0.5.0", + "log", + "objc", + "paste", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mime_guess" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "mio" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys 0.61.2", +] + +[[package]] +name = "mockall" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c84490118f2ee2d74570d114f3d0493cbf02790df303d2707606c3e14e07c96" +dependencies = [ + "cfg-if", + "downcast", + "fragile", + "lazy_static", + "mockall_derive", + "predicates", + "predicates-tree", +] + +[[package]] +name = "mockall_derive" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ce75669015c4f47b289fd4d4f56e894e4c96003ffdf3ac51313126f94c6cbb" +dependencies = [ + "cfg-if", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "move-abstract-interpreter" +version = "0.1.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" + +[[package]] +name = "move-abstract-stack" +version = "0.0.1" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" + +[[package]] +name = "move-binary-format" +version = "0.0.3" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "anyhow", + "enum-compat-util", + "indexmap 2.12.1", + "move-abstract-interpreter", + "move-core-types", + "move-proc-macros", + "ref-cast", + "serde", + "variant_count", +] + +[[package]] +name = "move-borrow-graph" +version = "0.0.1" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" + +[[package]] +name = "move-bytecode-source-map" +version = "0.1.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "anyhow", + "bcs", + "move-binary-format", + "move-command-line-common", + "move-core-types", + "move-ir-types", + "move-symbol-pool", + "serde", + "serde_json", +] + +[[package]] +name = "move-bytecode-utils" +version = "0.1.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "anyhow", + "indexmap 2.12.1", + "move-binary-format", + "move-core-types", + "petgraph 0.8.3", + "serde-reflection", +] + +[[package]] +name = "move-bytecode-verifier" +version = "0.1.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "move-abstract-interpreter", + "move-abstract-stack", + "move-binary-format", + "move-borrow-graph", + "move-bytecode-verifier-meter", + "move-core-types", + "move-regex-borrow-graph", + "move-vm-config", + "petgraph 0.8.3", +] + +[[package]] +name = "move-bytecode-verifier-meter" +version = "0.1.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "move-binary-format", + "move-core-types", + "move-vm-config", +] + +[[package]] +name = "move-command-line-common" +version = "0.1.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "anyhow", + "bcs", + "colored", + "dirs-next", + "hex", + "insta", + "move-binary-format", + "move-core-types", + "once_cell", + "packed_struct", + "serde", + "sha2 0.9.9", + "vfs", + "walkdir", +] + +[[package]] +name = "move-compiler" +version = "0.0.1" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "anyhow", + "bcs", + "clap", + "codespan-reporting", + "dunce", + "hex", + "insta", + "lsp-types 0.95.1", + "move-abstract-interpreter", + "move-binary-format", + "move-borrow-graph", + "move-bytecode-source-map", + "move-bytecode-verifier", + "move-command-line-common", + "move-core-types", + "move-ir-to-bytecode", + "move-ir-types", + "move-proc-macros", + "move-symbol-pool", + "once_cell", + "petgraph 0.8.3", + "rayon", + "regex", + "serde", + "serde_json", + "similar", + "stacker", + "tempfile", + "vfs", +] + +[[package]] +name = "move-core-types" +version = "0.0.4" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "anyhow", + "bcs", + "enum-compat-util", + "ethnum", + "hex", + "indexmap 2.12.1", + "leb128", + "move-proc-macros", + "num", + "once_cell", + "primitive-types 0.10.1", + "rand 0.8.5", + "ref-cast", + "serde", + "serde_bytes", + "serde_with", + "thiserror 1.0.69", + "uint", +] + +[[package]] +name = "move-coverage" +version = "0.1.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "anyhow", + "bcs", + "clap", + "codespan", + "colored", + "indexmap 2.12.1", + "lcov", + "move-abstract-interpreter", + "move-binary-format", + "move-bytecode-source-map", + "move-bytecode-verifier", + "move-command-line-common", + "move-compiler", + "move-core-types", + "move-ir-types", + "move-trace-format", + "petgraph 0.8.3", + "serde", +] + +[[package]] +name = "move-disassembler" +version = "0.1.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "anyhow", + "bcs", + "clap", + "hex", + "inline_colorization", + "move-abstract-interpreter", + "move-binary-format", + "move-bytecode-source-map", + "move-command-line-common", + "move-compiler", + "move-core-types", + "move-coverage", + "move-ir-types", + "move-symbol-pool", +] + +[[package]] +name = "move-ir-to-bytecode" +version = "0.1.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "anyhow", + "codespan-reporting", + "log", + "move-binary-format", + "move-bytecode-source-map", + "move-command-line-common", + "move-core-types", + "move-ir-to-bytecode-syntax", + "move-ir-types", + "move-symbol-pool", + "ouroboros", +] + +[[package]] +name = "move-ir-to-bytecode-syntax" +version = "0.1.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "anyhow", + "hex", + "move-command-line-common", + "move-core-types", + "move-ir-types", + "move-symbol-pool", +] + +[[package]] +name = "move-ir-types" +version = "0.1.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "hex", + "move-command-line-common", + "move-core-types", + "move-symbol-pool", + "once_cell", + "serde", +] + +[[package]] +name = "move-proc-macros" +version = "0.1.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "enum-compat-util", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "move-regex-borrow-graph" +version = "0.0.1" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "itertools 0.10.5", + "move-binary-format", + "move-core-types", + "petgraph 0.8.3", + "proptest", +] + +[[package]] +name = "move-symbol-pool" +version = "0.1.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "once_cell", + "phf", + "serde", +] + +[[package]] +name = "move-trace-format" +version = "0.0.1" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "move-binary-format", + "move-core-types", + "serde", + "serde_json", + "zstd", +] + +[[package]] +name = "move-vm-config" +version = "0.1.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "move-binary-format", + "once_cell", +] + +[[package]] +name = "move-vm-profiler" +version = "0.1.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "move-trace-format", + "move-vm-config", + "once_cell", + "serde", + "serde_json", + "tracing", +] + +[[package]] +name = "move-vm-test-utils" +version = "0.1.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "anyhow", + "move-binary-format", + "move-core-types", + "move-vm-profiler", + "move-vm-types", + "once_cell", + "serde", +] + +[[package]] +name = "move-vm-types" +version = "0.1.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "bcs", + "move-binary-format", + "move-core-types", + "move-vm-profiler", + "serde", + "smallvec", +] + +[[package]] +name = "moxcms" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80986bbbcf925ebd3be54c26613d861255284584501595cf418320c078945608" +dependencies = [ + "num-traits", + "pxfm", +] + +[[package]] +name = "msim-macros" +version = "0.1.0" +source = "git+https://github.com/MystenLabs/mysten-sim.git?rev=427147994705914a2f5afa42bc140794e31113b9#427147994705914a2f5afa42bc140794e31113b9" +dependencies = [ + "darling 0.14.4", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "multiaddr" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b36f567c7099511fa8612bbbb52dda2419ce0bdbacf31714e3a5ffdb766d3bd" +dependencies = [ + "arrayref", + "byteorder", + "data-encoding", + "log", + "multibase", + "multihash", + "percent-encoding", + "serde", + "static_assertions", + "unsigned-varint", + "url", +] + +[[package]] +name = "multibase" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8694bb4835f452b0e3bb06dbebb1d6fc5385b6ca1caf2e55fd165c042390ec77" +dependencies = [ + "base-x", + "base256emoji", + "data-encoding", + "data-encoding-macro", +] + +[[package]] +name = "multihash" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835d6ff01d610179fbce3de1694d007e500bf33a7f29689838941d6bf783ae40" +dependencies = [ + "core2", + "multihash-derive", + "unsigned-varint", +] + +[[package]] +name = "multihash-derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6d4752e6230d8ef7adf7bd5d8c4b1f6561c1014c5ba9a37445ccefe18aa1db" +dependencies = [ + "proc-macro-crate 1.1.3", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", + "synstructure 0.12.6", +] + +[[package]] +name = "mysten-common" +version = "0.1.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "antithesis_sdk", + "anyhow", + "either", + "fastcrypto", + "futures", + "mysten-metrics", + "once_cell", + "parking_lot", + "rand 0.8.5", + "reqwest 0.12.24", + "serde_json", + "snap", + "sui-macros", + "tempfile", + "tokio", + "tracing", +] + +[[package]] +name = "mysten-metrics" +version = "0.7.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "async-trait", + "axum 0.8.7", + "dashmap", + "futures", + "once_cell", + "parking_lot", + "prometheus", + "prometheus-closure-metric", + "scopeguard", + "simple-server-timing-header", + "tap", + "tokio", + "tracing", + "uuid", +] + +[[package]] +name = "mysten-network" +version = "0.2.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "anemo", + "anemo-tower", + "anyhow", + "async-stream", + "bcs", + "bytes", + "dashmap", + "eyre", + "fastcrypto", + "futures", + "http 1.3.1", + "http-body 1.0.1", + "hyper-rustls 0.27.7", + "hyper-util", + "multiaddr", + "mysten-metrics", + "once_cell", + "pin-project-lite", + "prometheus", + "quinn-proto", + "rand 0.8.5", + "rustls 0.23.35", + "serde", + "snap", + "sui-http", + "tokio", + "tokio-rustls 0.26.4", + "tokio-stream", + "tonic 0.14.2", + "tonic-health", + "tower 0.5.2", + "tower-http 0.5.2", + "tracing", +] + +[[package]] +name = "naga" +version = "23.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "364f94bc34f61332abebe8cad6f6cd82a5b65cff22c828d05d0968911462ca4f" +dependencies = [ + "arrayvec", + "bit-set 0.8.0", + "bitflags 2.10.0", + "cfg_aliases 0.1.1", + "codespan-reporting", + "hexf-parse", + "indexmap 2.12.1", + "log", + "pp-rs", + "rustc-hash 1.1.0", + "spirv", + "termcolor", + "thiserror 1.0.69", + "unicode-xid", +] + +[[package]] +name = "naga_oil" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31ea1f080bb359927cd5404d0af1e5e6758f4f2d82ecfbebb0a0c434764e40f1" +dependencies = [ + "bit-set 0.5.3", + "codespan-reporting", + "data-encoding", + "indexmap 2.12.1", + "naga", + "once_cell", + "regex", + "regex-syntax 0.8.8", + "rustc-hash 1.1.0", + "thiserror 1.0.69", + "tracing", + "unicode-ident", +] + +[[package]] +name = "native-tls" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework 2.11.1", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "ndk" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" +dependencies = [ + "bitflags 2.10.0", + "jni-sys", + "log", + "ndk-sys 0.6.0+11769913", + "num_enum 0.7.5", + "raw-window-handle", + "thiserror 1.0.69", +] + +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + +[[package]] +name = "ndk-sys" +version = "0.5.0+25.2.9519653" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "ndk-sys" +version = "0.6.0+11769913" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "neptune" +version = "13.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06626c9ac04c894e9a23d061ba1309f28506cdc5fe64156d28a15fb57fc8e438" +dependencies = [ + "bellpepper", + "bellpepper-core", + "blake2s_simd", + "blstrs", + "byteorder", + "ff 0.13.1", + "generic-array 0.14.7", + "log", + "pasta_curves 0.5.1", + "serde", + "trait-set", +] + +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + +[[package]] +name = "nibble_vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" +dependencies = [ + "smallvec", +] + +[[package]] +name = "nix" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" +dependencies = [ + "bitflags 2.10.0", + "cfg-if", + "cfg_aliases 0.1.1", + "libc", +] + +[[package]] +name = "nix" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" +dependencies = [ + "bitflags 2.10.0", + "cfg-if", + "cfg_aliases 0.2.1", + "libc", +] + +[[package]] +name = "no-std-compat" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c" + +[[package]] +name = "no_std_strings" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5b0c77c1b780822bc749a33e39aeb2c07584ab93332303babeabb645298a76e" + +[[package]] +name = "nohash-hasher" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "nonempty" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "995defdca0a589acfdd1bd2e8e3b896b4d4f7675a31fd14c32611440c7f608e6" +dependencies = [ + "serde", +] + +[[package]] +name = "nonmax" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "610a5acd306ec67f907abe5567859a3c693fb9886eb1f012ab8f2a47bef3db51" + +[[package]] +name = "nonzero_ext" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21" + +[[package]] +name = "normalize-line-endings" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" + +[[package]] +name = "ntapi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" +dependencies = [ + "winapi", +] + +[[package]] +name = "nu-ansi-term" +version = "0.50.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "num" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" +dependencies = [ + "num-bigint 0.4.6", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6f7833f2cbf2360a6cfd58cd41a53aa7a90bd4c202f5b1c7dd2ed73c57b2c3" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "num-bigint-dig" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e661dda6640fad38e827a6d4a310ff4763082116fe217f279885c97f511bb0b7" +dependencies = [ + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand 0.8.5", + "smallvec", + "zeroize", +] + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-modular" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17bb261bf36fa7d83f4c294f834e91256769097b3cb505d44831e0a179ac647f" + +[[package]] +name = "num-order" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "537b596b97c40fcf8056d153049eb22f481c17ebce72a513ec9286e4986d1bb6" +dependencies = [ + "num-modular", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint 0.4.6", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +dependencies = [ + "num_enum_derive 0.5.11", +] + +[[package]] +name = "num_enum" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" +dependencies = [ + "num_enum_derive 0.6.1", +] + +[[package]] +name = "num_enum" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c" +dependencies = [ + "num_enum_derive 0.7.5", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +dependencies = [ + "proc-macro-crate 1.1.3", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "num_enum_derive" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" +dependencies = [ + "proc-macro-crate 1.1.3", + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" +dependencies = [ + "proc-macro-crate 3.4.0", + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + +[[package]] +name = "nybbles" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c4b5ecbd0beec843101bffe848217f770e8b8da81d8355b7d6e226f2199b3dc" +dependencies = [ + "alloy-rlp", + "cfg-if", + "proptest", + "ruint", + "serde", + "smallvec", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", +] + +[[package]] +name = "objc-sys" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" + +[[package]] +name = "objc2" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" +dependencies = [ + "objc-sys", + "objc2-encode", +] + +[[package]] +name = "objc2" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c2599ce0ec54857b29ce62166b0ed9b4f6f1a70ccc9a71165b6154caca8c05" +dependencies = [ + "objc2-encode", +] + +[[package]] +name = "objc2-app-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" +dependencies = [ + "bitflags 2.10.0", + "block2 0.5.1", + "libc", + "objc2 0.5.2", + "objc2-core-data", + "objc2-core-image", + "objc2-foundation", + "objc2-quartz-core", +] + +[[package]] +name = "objc2-cloud-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" +dependencies = [ + "bitflags 2.10.0", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-core-location", + "objc2-foundation", +] + +[[package]] +name = "objc2-contacts" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-data" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" +dependencies = [ + "bitflags 2.10.0", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-image" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation", + "objc2-metal", +] + +[[package]] +name = "objc2-core-location" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.2", + "objc2-contacts", + "objc2-foundation", +] + +[[package]] +name = "objc2-encode" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" + +[[package]] +name = "objc2-foundation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" +dependencies = [ + "bitflags 2.10.0", + "block2 0.5.1", + "dispatch", + "libc", + "objc2 0.5.2", +] + +[[package]] +name = "objc2-link-presentation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.2", + "objc2-app-kit", + "objc2-foundation", +] + +[[package]] +name = "objc2-metal" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" +dependencies = [ + "bitflags 2.10.0", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" +dependencies = [ + "bitflags 2.10.0", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation", + "objc2-metal", +] + +[[package]] +name = "objc2-symbols" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" +dependencies = [ + "objc2 0.5.2", + "objc2-foundation", +] + +[[package]] +name = "objc2-ui-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" +dependencies = [ + "bitflags 2.10.0", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-cloud-kit", + "objc2-core-data", + "objc2-core-image", + "objc2-core-location", + "objc2-foundation", + "objc2-link-presentation", + "objc2-quartz-core", + "objc2-symbols", + "objc2-uniform-type-identifiers", + "objc2-user-notifications", +] + +[[package]] +name = "objc2-uniform-type-identifiers" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation", +] + +[[package]] +name = "objc2-user-notifications" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" +dependencies = [ + "bitflags 2.10.0", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-core-location", + "objc2-foundation", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "object" +version = "0.37.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" +dependencies = [ + "memchr", +] + +[[package]] +name = "object_store" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cfccb68961a56facde1163f9319e0d15743352344e7808a11795fb99698dcaf" +dependencies = [ + "async-trait", + "base64 0.22.1", + "bytes", + "chrono", + "futures", + "httparse", + "humantime", + "hyper 1.8.1", + "itertools 0.13.0", + "md-5", + "parking_lot", + "percent-encoding", + "quick-xml", + "rand 0.8.5", + "reqwest 0.12.24", + "ring", + "rustls-pemfile 2.2.0", + "serde", + "serde_json", + "snafu", + "tokio", + "tracing", + "url", + "walkdir", +] + +[[package]] +name = "offset-allocator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e234d535da3521eb95106f40f0b73483d80bfb3aacf27c40d7e2b72f1a3e00a2" +dependencies = [ + "log", + "nonmax", +] + +[[package]] +name = "oid-registry" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12f40cff3dde1b6087cc5d5f5d4d65712f34016a03ed60e9c08dcc392736b5b7" +dependencies = [ + "asn1-rs", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "openssl" +version = "0.10.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328" +dependencies = [ + "bitflags 2.10.0", + "cfg-if", + "foreign-types 0.3.2", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "openssl-probe" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" + +[[package]] +name = "openssl-sys" +version = "0.9.111" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "orbclient" +version = "0.3.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "247ad146e19b9437f8604c21f8652423595cf710ad108af40e77d3ae6e96b827" +dependencies = [ + "libredox", +] + +[[package]] +name = "ouroboros" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2ba07320d39dfea882faa70554b4bd342a5f273ed59ba7c1c6b4c840492c954" +dependencies = [ + "aliasable", + "ouroboros_macro", + "static_assertions", +] + +[[package]] +name = "ouroboros_macro" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec4c6225c69b4ca778c0aea097321a64c421cf4577b331c61b229267edabb6f8" +dependencies = [ + "heck 0.4.1", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "outref" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e" + +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", + "primeorder", + "sha2 0.10.9", +] + +[[package]] +name = "p3-air" +version = "0.2.3-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d05a97452c4b1cfa8626e69181d901fc8231d99ff7d87e9701a2e6b934606615" +dependencies = [ + "p3-field", + "p3-matrix", +] + +[[package]] +name = "p3-baby-bear" +version = "0.2.3-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7521838ecab2ddf4f7bc4ceebad06ec02414729598485c1ada516c39900820e8" +dependencies = [ + "num-bigint 0.4.6", + "p3-field", + "p3-mds", + "p3-poseidon2", + "p3-symmetric", + "rand 0.8.5", + "serde", +] + +[[package]] +name = "p3-bn254-fr" +version = "0.2.3-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0dd4d095d254783098bd09fc5fdf33fd781a1be54608ab93cb3ed4bd723da54" +dependencies = [ + "ff 0.13.1", + "num-bigint 0.4.6", + "p3-field", + "p3-poseidon2", + "p3-symmetric", + "rand 0.8.5", + "serde", +] + +[[package]] +name = "p3-challenger" +version = "0.2.3-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5d18c223b7e0177f4ac91070fa3f6cc557d5ee3b279869924c3102fb1b20910" +dependencies = [ + "p3-field", + "p3-maybe-rayon", + "p3-symmetric", + "p3-util", + "serde", + "tracing", +] + +[[package]] +name = "p3-commit" +version = "0.2.3-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b38fe979d53d4f1d64158c40b3cd9ea1bd6b7bc8f085e489165c542ef914ae28" +dependencies = [ + "itertools 0.12.1", + "p3-challenger", + "p3-field", + "p3-matrix", + "p3-util", + "serde", +] + +[[package]] +name = "p3-dft" +version = "0.2.3-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46414daedd796f1eefcdc1811c0484e4bced5729486b6eaba9521c572c76761a" +dependencies = [ + "p3-field", + "p3-matrix", + "p3-maybe-rayon", + "p3-util", + "tracing", +] + +[[package]] +name = "p3-field" +version = "0.2.3-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48948a0516b349e9d1cdb95e7236a6ee010c44e68c5cc78b4b92bf1c4022a0d9" +dependencies = [ + "itertools 0.12.1", + "num-bigint 0.4.6", + "num-traits", + "p3-util", + "rand 0.8.5", + "serde", +] + +[[package]] +name = "p3-fri" +version = "0.2.3-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c274dab2dcd060cdea9ab3f8f7129f5fa5f08917d6092dc2b297a31d883aa0" +dependencies = [ + "itertools 0.12.1", + "p3-challenger", + "p3-commit", + "p3-dft", + "p3-field", + "p3-interpolation", + "p3-matrix", + "p3-maybe-rayon", + "p3-util", + "serde", + "tracing", +] + +[[package]] +name = "p3-interpolation" +version = "0.2.3-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed8de7333abb0ad0a17bb78726a43749cc7fcab4763f296894e8b2933841d4d8" +dependencies = [ + "p3-field", + "p3-matrix", + "p3-util", +] + +[[package]] +name = "p3-keccak-air" +version = "0.2.3-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01c7ec21317c455d39588428e4ec85b96d663ff171ddf102a10e2ca54c942dea" +dependencies = [ + "p3-air", + "p3-field", + "p3-matrix", + "p3-maybe-rayon", + "p3-util", + "tracing", +] + +[[package]] +name = "p3-matrix" +version = "0.2.3-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e4de3f373589477cb735ea58e125898ed20935e03664b4614c7fac258b3c42f" +dependencies = [ + "itertools 0.12.1", + "p3-field", + "p3-maybe-rayon", + "p3-util", + "rand 0.8.5", + "serde", + "tracing", +] + +[[package]] +name = "p3-maybe-rayon" +version = "0.2.3-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3968ad1160310296eb04f91a5f4edfa38fe1d6b2b8cd6b5c64e6f9b7370979e" +dependencies = [ + "rayon", +] + +[[package]] +name = "p3-mds" +version = "0.2.3-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2356b1ed0add6d5dfbf7a338ce534a6fde827374394a52cec16a0840af6e97c9" +dependencies = [ + "itertools 0.12.1", + "p3-dft", + "p3-field", + "p3-matrix", + "p3-symmetric", + "p3-util", + "rand 0.8.5", +] + +[[package]] +name = "p3-merkle-tree" +version = "0.2.3-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f159e073afbee02c00d22390bf26ebb9ce03bbcd3e6dcd13c6a7a3811ab39608" +dependencies = [ + "itertools 0.12.1", + "p3-commit", + "p3-field", + "p3-matrix", + "p3-maybe-rayon", + "p3-symmetric", + "p3-util", + "serde", + "tracing", +] + +[[package]] +name = "p3-poseidon2" +version = "0.2.3-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da1eec7e1b6900581bedd95e76e1ef4975608dd55be9872c9d257a8a9651c3a" +dependencies = [ + "gcd", + "p3-field", + "p3-mds", + "p3-symmetric", + "rand 0.8.5", + "serde", +] + +[[package]] +name = "p3-symmetric" +version = "0.2.3-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edb439bea1d822623b41ff4b51e3309e80d13cadf8b86d16ffd5e6efb9fdc360" +dependencies = [ + "itertools 0.12.1", + "p3-field", + "serde", +] + +[[package]] +name = "p3-uni-stark" +version = "0.2.3-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a86f29c32bf46fa4acb6547d2065a711e146d4faca388b56d75718c60a0097d" +dependencies = [ + "itertools 0.12.1", + "p3-air", + "p3-challenger", + "p3-commit", + "p3-dft", + "p3-field", + "p3-matrix", + "p3-maybe-rayon", + "p3-util", + "serde", + "tracing", +] + +[[package]] +name = "p3-util" +version = "0.2.3-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c2c2010678b9332b563eaa38364915b585c1a94b5ca61e2c7541c087ddda5c" +dependencies = [ + "serde", +] + +[[package]] +name = "p384" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe42f1670a52a47d448f14b6a5c61dd78fce51856e68edaa38f7ae3a46b8d6b6" +dependencies = [ + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", + "primeorder", + "sha2 0.10.9", +] + +[[package]] +name = "packed_struct" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36b29691432cc9eff8b282278473b63df73bea49bc3ec5e67f31a3ae9c3ec190" +dependencies = [ + "bitvec 1.0.1", + "packed_struct_codegen", + "serde", +] + +[[package]] +name = "packed_struct_codegen" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cd6706dfe50d53e0f6aa09e12c034c44faacd23e966ae5a209e8bdb8f179f98" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "pairing" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "135590d8bdba2b31346f9cd1fb2a912329f5135e832a4f422942eb6ead8b6b3b" +dependencies = [ + "group 0.12.1", +] + +[[package]] +name = "pairing" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fec4625e73cf41ef4bb6846cafa6d44736525f442ba45e407c4a000a13996f" +dependencies = [ + "group 0.13.0", +] + +[[package]] +name = "papergrid" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae7891b22598926e4398790c8fe6447930c72a67d36d983a49d6ce682ce83290" +dependencies = [ + "bytecount", + "fnv", + "unicode-width 0.1.14", +] + +[[package]] +name = "parity-scale-codec" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "373b1a4c1338d9cd3d1fa53b3a11bdab5ab6bd80a20f7f7becd76953ae2be909" +dependencies = [ + "arrayvec", + "bitvec 0.20.4", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive 2.3.1", + "serde", +] + +[[package]] +name = "parity-scale-codec" +version = "3.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799781ae679d79a948e13d4824a40970bfa500058d245760dd857301059810fa" +dependencies = [ + "arrayvec", + "bitvec 1.0.1", + "byte-slice-cast", + "const_format", + "impl-trait-for-tuples", + "parity-scale-codec-derive 3.7.5", + "rustversion", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1557010476e0595c9b568d16dcfb81b93cdeb157612726f5170d31aa707bed27" +dependencies = [ + "proc-macro-crate 1.1.3", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34b4653168b563151153c9e4c08ebed57fb8262bebfa79711552fa983c623e7a" +dependencies = [ + "proc-macro-crate 3.4.0", + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.5.18", + "smallvec", + "windows-link", +] + +[[package]] +name = "passkey-types" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77144664f6aac5f629d7efa815f5098a054beeeca6ccafee5ec453fd2b0c53f9" +dependencies = [ + "bitflags 2.10.0", + "ciborium", + "coset", + "data-encoding", + "getrandom 0.2.16", + "hmac", + "indexmap 2.12.1", + "rand 0.8.5", + "serde", + "serde_json", + "sha2 0.10.9", + "strum 0.25.0", + "typeshare", + "zeroize", +] + +[[package]] +name = "pasta_curves" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc65faf8e7313b4b1fbaa9f7ca917a0eed499a9663be71477f87993604341d8" +dependencies = [ + "blake2b_simd", + "ff 0.12.1", + "group 0.12.1", + "lazy_static", + "rand 0.8.5", + "static_assertions", + "subtle", +] + +[[package]] +name = "pasta_curves" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e57598f73cc7e1b2ac63c79c517b31a0877cd7c402cdcaa311b5208de7a095" +dependencies = [ + "blake2b_simd", + "ff 0.13.1", + "group 0.13.0", + "hex", + "lazy_static", + "rand 0.8.5", + "serde", + "static_assertions", + "subtle", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pathdiff" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" + +[[package]] +name = "pbkdf2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "pem" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be" +dependencies = [ + "base64 0.22.1", + "serde_core", +] + +[[package]] +name = "pem-rfc7468" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d159833a9105500e0398934e205e0773f0b27529557134ecfc51c27646adac" +dependencies = [ + "base64ct", +] + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "pest" +version = "2.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbcfd20a6d4eeba40179f05735784ad32bdaef05ce8e8af05f180d45bb3e7e22" +dependencies = [ + "memchr", + "ucd-trie", +] + +[[package]] +name = "petgraph" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" +dependencies = [ + "fixedbitset 0.4.2", + "indexmap 2.12.1", +] + +[[package]] +name = "petgraph" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455" +dependencies = [ + "fixedbitset 0.5.7", + "hashbrown 0.15.5", + "indexmap 2.12.1", + "serde", +] + +[[package]] +name = "phf" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" +dependencies = [ + "phf_macros", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" +dependencies = [ + "phf_shared", + "rand 0.8.5", +] + +[[package]] +name = "phf_macros" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "phf_shared" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "piper" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" +dependencies = [ + "atomic-waker", + "fastrand", + "futures-io", +] + +[[package]] +name = "pkcs1" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eff33bdbdfc54cc98a2eca766ebdec3e1b8fb7387523d5c9c9a2891da856f719" +dependencies = [ + "der 0.6.1", + "pkcs8 0.9.0", + "spki 0.6.0", + "zeroize", +] + +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der 0.7.10", + "pkcs8 0.10.2", + "spki 0.7.3", +] + +[[package]] +name = "pkcs8" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +dependencies = [ + "der 0.6.1", + "spki 0.6.0", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der 0.7.10", + "spki 0.7.3", +] + +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] +name = "png" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97baced388464909d42d89643fe4361939af9b7ce7a31ee32a168f832a70f2a0" +dependencies = [ + "bitflags 2.10.0", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "polling" +version = "3.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi", + "pin-project-lite", + "rustix 1.1.2", + "windows-sys 0.61.2", +] + +[[package]] +name = "polyval" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "portable-atomic" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" + +[[package]] +name = "portable-atomic-util" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "postcard" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24" +dependencies = [ + "cobs", + "embedded-io 0.4.0", + "embedded-io 0.6.1", + "serde", +] + +[[package]] +name = "potential_utf" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +dependencies = [ + "zerovec", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "pp-rs" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb458bb7f6e250e6eb79d5026badc10a3ebb8f9a15d1fff0f13d17c71f4d6dee" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "predicates" +version = "2.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59230a63c37f3e18569bdb90e4a89cbf5bf8b06fea0b84e65ea10cc4df47addd" +dependencies = [ + "difflib", + "float-cmp", + "itertools 0.10.5", + "normalize-line-endings", + "predicates-core", + "regex", +] + +[[package]] +name = "predicates-core" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "727e462b119fe9c93fd0eb1429a5f7647394014cf3c04ab2c0350eeb09095ffa" + +[[package]] +name = "predicates-tree" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72dd2d6d381dfb73a193c7fca536518d7caee39fc8503f74e7dc0be0531b425c" +dependencies = [ + "predicates-core", + "termtree", +] + +[[package]] +name = "presser" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa" + +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn 2.0.110", +] + +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve 0.13.8", +] + +[[package]] +name = "primitive-types" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05e4722c697a58a99d5d06a08c30821d7c082a4632198de1eaa5a6c22ef42373" +dependencies = [ + "fixed-hash 0.7.0", + "impl-codec 0.5.1", + "impl-serde", + "uint", +] + +[[package]] +name = "primitive-types" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" +dependencies = [ + "fixed-hash 0.8.0", + "impl-codec 0.6.0", + "uint", +] + +[[package]] +name = "proc-macro-crate" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" +dependencies = [ + "thiserror 1.0.69", + "toml 0.5.11", +] + +[[package]] +name = "proc-macro-crate" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" +dependencies = [ + "toml_edit 0.23.7", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "proc-macro2" +version = "1.0.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "proc-macro2-diagnostics" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", + "version_check", +] + +[[package]] +name = "profiling" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773" + +[[package]] +name = "prometheus" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d33c28a30771f7f96db69893f78b857f7450d7e0237e9c8fc6427a81bae7ed1" +dependencies = [ + "cfg-if", + "fnv", + "lazy_static", + "memchr", + "parking_lot", + "protobuf", + "thiserror 1.0.69", +] + +[[package]] +name = "prometheus-closure-metric" +version = "0.1.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "anyhow", + "prometheus", + "protobuf", +] + +[[package]] +name = "proptest" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bee689443a2bd0a16ab0348b52ee43e3b2d1b1f931c8aa5c9f8de4c86fbe8c40" +dependencies = [ + "bit-set 0.8.0", + "bit-vec 0.8.0", + "bitflags 2.10.0", + "num-traits", + "rand 0.9.2", + "rand_chacha 0.9.0", + "rand_xorshift 0.4.0", + "regex-syntax 0.8.8", + "rusty-fork", + "tempfile", + "unarray", +] + +[[package]] +name = "proptest-derive" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ee1c9ac207483d5e7db4940700de86a9aae46ef90c48b57f99fe7edb8345e49" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "prost" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5" +dependencies = [ + "bytes", + "prost-derive 0.13.5", +] + +[[package]] +name = "prost" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7231bd9b3d3d33c86b58adbac74b5ec0ad9f496b19d22801d773636feaa95f3d" +dependencies = [ + "bytes", + "prost-derive 0.14.1", +] + +[[package]] +name = "prost-derive" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d" +dependencies = [ + "anyhow", + "itertools 0.14.0", + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "prost-derive" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9120690fafc389a67ba3803df527d0ec9cbbc9cc45e4cc20b332996dfb672425" +dependencies = [ + "anyhow", + "itertools 0.14.0", + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "prost-types" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9b4db3d6da204ed77bb26ba83b6122a73aeb2e87e25fbf7ad2e84c4ccbf8f72" +dependencies = [ + "prost 0.14.1", +] + +[[package]] +name = "protobuf" +version = "2.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94" +dependencies = [ + "bytes", +] + +[[package]] +name = "psm" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d11f2fedc3b7dafdc2851bc52f277377c5473d378859be234bc7ebb593144d01" +dependencies = [ + "ar_archive_writer", + "cc", +] + +[[package]] +name = "pxfm" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3502d6155304a4173a5f2c34b52b7ed0dd085890326cb50fd625fdf39e86b3b" +dependencies = [ + "num-traits", +] + +[[package]] +name = "quanta" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3ab5a9d756f0d97bdc89019bd2e4ea098cf9cde50ee7564dde6b81ccc8f06c7" +dependencies = [ + "crossbeam-utils", + "libc", + "once_cell", + "raw-cpuid", + "wasi", + "web-sys", + "winapi", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quick-xml" +version = "0.37.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "quinn" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +dependencies = [ + "bytes", + "cfg_aliases 0.2.1", + "futures-io", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash 2.1.1", + "rustls 0.23.35", + "socket2 0.6.1", + "thiserror 2.0.17", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" +dependencies = [ + "bytes", + "fastbloom", + "getrandom 0.3.4", + "lru-slab", + "rand 0.9.2", + "ring", + "rustc-hash 2.1.1", + "rustls 0.23.35", + "rustls-pki-types", + "slab", + "thiserror 2.0.17", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" +dependencies = [ + "cfg_aliases 0.2.1", + "libc", + "once_cell", + "socket2 0.6.1", + "tracing", + "windows-sys 0.60.2", +] + +[[package]] +name = "quote" +version = "1.0.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "radium" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb" + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "radix_trie" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" +dependencies = [ + "endian-type", + "nibble_vec", +] + +[[package]] +name = "radsort" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "019b4b213425016d7d84a153c4c73afb0946fbb4840e4eece7ba8848b9d6da22" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", + "serde", +] + +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", + "serde", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.16", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.4", + "serde", +] + +[[package]] +name = "rand_distr" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "rand_xorshift" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "rand_xorshift" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" +dependencies = [ + "rand_core 0.9.3", +] + +[[package]] +name = "rand_xoshiro" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "range-alloc" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d6831663a5098ea164f89cff59c6284e95f4e3c76ce9848d4529f5ccca9bde" + +[[package]] +name = "range-set-blaze" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8421b5d459262eabbe49048d362897ff3e3830b44eac6cfe341d6acb2f0f13d2" +dependencies = [ + "gen_ops", + "itertools 0.12.1", + "num-integer", + "num-traits", +] + +[[package]] +name = "rangemap" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbbbbea733ec66275512d0b9694f34102e7d5406fdbe2ad8d21b28dce92887c" + +[[package]] +name = "ratatui" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eabd94c2f37801c20583fc49dd5cd6b0ba68c716787c2dd6ed18571e1e63117b" +dependencies = [ + "bitflags 2.10.0", + "cassowary", + "compact_str", + "crossterm 0.28.1", + "indoc", + "instability", + "itertools 0.13.0", + "lru 0.12.5", + "paste", + "strum 0.26.3", + "unicode-segmentation", + "unicode-truncate", + "unicode-width 0.2.0", +] + +[[package]] +name = "raw-cpuid" +version = "11.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186" +dependencies = [ + "bitflags 2.10.0", +] + +[[package]] +name = "raw-window-handle" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" + +[[package]] +name = "rayon" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "rayon-scan" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f87cc11a0140b4b0da0ffc889885760c61b13672d80a908920b2c0df078fa14" +dependencies = [ + "rayon", +] + +[[package]] +name = "rcgen" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75e669e5202259b5314d1ea5397316ad400819437857b90861765f24c4cf80a2" +dependencies = [ + "pem", + "ring", + "rustls-pki-types", + "time", + "yasna", +] + +[[package]] +name = "read-fonts" +version = "0.22.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69aacb76b5c29acfb7f90155d39759a29496aebb49395830e928a9703d2eec2f" +dependencies = [ + "bytemuck", + "font-types", +] + +[[package]] +name = "readonly" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2a62d85ed81ca5305dc544bd42c8804c5060b78ffa5ad3c64b0fb6a8c13d062" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "rectangle-pack" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0d463f2884048e7153449a55166f91028d5b0ea53c79377099ce4e8cf0cf9bb" + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags 2.10.0", +] + +[[package]] +name = "redox_users" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +dependencies = [ + "getrandom 0.2.16", + "libredox", + "thiserror 1.0.69", +] + +[[package]] +name = "redox_users" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" +dependencies = [ + "getrandom 0.2.16", + "libredox", + "thiserror 2.0.17", +] + +[[package]] +name = "ref-cast" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "regex" +version = "1.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax 0.8.8", +] + +[[package]] +name = "regex-automata" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.8", +] + +[[package]] +name = "regex-lite" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d942b98df5e658f56f20d592c7f868833fe38115e65c33003d8cd224b0155da" + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" + +[[package]] +name = "renderdoc-sys" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" + +[[package]] +name = "reqwest" +version = "0.11.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +dependencies = [ + "base64 0.21.7", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2 0.3.27", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.32", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile 1.0.4", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper 0.1.2", + "system-configuration", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + +[[package]] +name = "reqwest" +version = "0.12.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d0946410b9f7b082a427e4ef5c8ff541a88b357bc6c637c40db3a68ac70a36f" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2 0.4.12", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "hyper 1.8.1", + "hyper-rustls 0.27.7", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls 0.23.35", + "rustls-native-certs 0.8.2", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper 1.0.2", + "tokio", + "tokio-rustls 0.26.4", + "tokio-util", + "tower 0.5.2", + "tower-http 0.6.6", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "webpki-roots", +] + +[[package]] +name = "reqwest-middleware" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "562ceb5a604d3f7c885a792d42c199fd8af239d0a51b2fa6a78aafa092452b04" +dependencies = [ + "anyhow", + "async-trait", + "http 1.3.1", + "reqwest 0.12.24", + "serde", + "thiserror 1.0.69", + "tower-service", +] + +[[package]] +name = "rfc6979" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +dependencies = [ + "crypto-bigint 0.4.9", + "hmac", + "zeroize", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.16", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "risc0-binfmt" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c8f97f81bcdead4101bca06469ecef481a2695cd04e7e877b49dea56a7f6f2a" +dependencies = [ + "anyhow", + "borsh", + "bytemuck", + "derive_more 2.0.1", + "elf", + "lazy_static", + "postcard", + "rand 0.9.2", + "risc0-zkp", + "risc0-zkvm-platform", + "ruint", + "semver 1.0.27", + "serde", + "tracing", +] + +[[package]] +name = "risc0-build" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bbb512d728e011d03ce0958ca7954624ee13a215bcafd859623b3c63b2a3f60" +dependencies = [ + "anyhow", + "cargo_metadata 0.19.2", + "derive_builder", + "dirs 6.0.0", + "docker-generate", + "hex", + "risc0-binfmt", + "risc0-zkos-v1compat", + "risc0-zkp", + "risc0-zkvm-platform", + "rzup", + "semver 1.0.27", + "serde", + "serde_json", + "stability", + "tempfile", +] + +[[package]] +name = "risc0-circuit-keccak" +version = "4.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f195f865ac1afdc21a172d7756fdcc21be18e13eb01d78d3d7f2b128fa881ba" +dependencies = [ + "anyhow", + "bytemuck", + "paste", + "risc0-binfmt", + "risc0-circuit-recursion", + "risc0-core", + "risc0-zkp", + "tracing", +] + +[[package]] +name = "risc0-circuit-recursion" +version = "4.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dca8f15c8abc0fd8c097aa7459879110334d191c63dd51d4c28881c4a497279e" +dependencies = [ + "anyhow", + "bytemuck", + "hex", + "metal", + "risc0-core", + "risc0-zkp", + "tracing", +] + +[[package]] +name = "risc0-circuit-rv32im" +version = "4.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1b0689f4a270a2f247b04397ebb431b8f64fe5170e98ee4f9d71bd04825205" +dependencies = [ + "anyhow", + "bit-vec 0.8.0", + "bytemuck", + "derive_more 2.0.1", + "paste", + "risc0-binfmt", + "risc0-core", + "risc0-zkp", + "serde", + "tracing", +] + +[[package]] +name = "risc0-core" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80f2723fedace48c6c5a505bd8f97ac4e1712bc4cb769083e10536d862b66987" +dependencies = [ + "bytemuck", + "rand_core 0.9.3", +] + +[[package]] +name = "risc0-groth16" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "724285dc79604abfb2d40feaefe3e335420a6b293511661f77d6af62f1f5fae9" +dependencies = [ + "anyhow", + "ark-bn254 0.5.0", + "ark-ec 0.5.0", + "ark-ff 0.5.0", + "ark-groth16 0.5.0", + "ark-serialize 0.5.0", + "bytemuck", + "hex", + "num-bigint 0.4.6", + "num-traits", + "risc0-binfmt", + "risc0-zkp", + "serde", +] + +[[package]] +name = "risc0-zkos-v1compat" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "840c2228803557a8b7dc035a8f196516b6fd68c9dc6ac092f0c86241b5b1bafb" +dependencies = [ + "include_bytes_aligned", + "no_std_strings", + "risc0-zkvm-platform", +] + +[[package]] +name = "risc0-zkp" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb6bf356f469bb8744f72a07a37134c5812c1d55d6271bba80e87bdb7a58c8e" +dependencies = [ + "anyhow", + "blake2", + "borsh", + "bytemuck", + "cfg-if", + "digest 0.10.7", + "hex", + "hex-literal", + "metal", + "paste", + "rand_core 0.9.3", + "risc0-core", + "risc0-zkvm-platform", + "serde", + "sha2 0.10.9", + "stability", + "tracing", +] + +[[package]] +name = "risc0-zkvm" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fcce11648a9ff60b8e7af2f0ce7fbf8d25275ab6d414cc91b9da69ee75bc978" +dependencies = [ + "anyhow", + "bincode", + "bonsai-sdk", + "borsh", + "bytemuck", + "bytes", + "derive_more 2.0.1", + "hex", + "lazy-regex", + "prost 0.13.5", + "risc0-binfmt", + "risc0-build", + "risc0-circuit-keccak", + "risc0-circuit-recursion", + "risc0-circuit-rv32im", + "risc0-core", + "risc0-groth16", + "risc0-zkos-v1compat", + "risc0-zkp", + "risc0-zkvm-platform", + "rrs-lib", + "rzup", + "semver 1.0.27", + "serde", + "sha2 0.10.9", + "stability", + "tempfile", + "tracing", +] + +[[package]] +name = "risc0-zkvm-platform" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfaa10feba15828c788837ddde84b994393936d8f5715228627cfe8625122a40" +dependencies = [ + "bytemuck", + "cfg-if", + "getrandom 0.2.16", + "getrandom 0.3.4", + "libm", + "num_enum 0.7.5", + "paste", + "stability", +] + +[[package]] +name = "rlp" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" +dependencies = [ + "bytes", + "rustc-hex", +] + +[[package]] +name = "roaring" +version = "0.10.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19e8d2cfa184d94d0726d650a9f4a1be7f9b76ac9fdb954219878dc00c1c1e7b" +dependencies = [ + "bytemuck", + "byteorder", +] + +[[package]] +name = "roaring" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f08d6a905edb32d74a5d5737a0c9d7e950c312f3c46cb0ca0a2ca09ea11878a0" +dependencies = [ + "bytemuck", + "byteorder", +] + +[[package]] +name = "ron" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" +dependencies = [ + "base64 0.21.7", + "bitflags 2.10.0", + "serde", + "serde_derive", +] + +[[package]] +name = "ron" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db09040cc89e461f1a265139777a2bde7f8d8c67c4936f700c63ce3e2904d468" +dependencies = [ + "base64 0.22.1", + "bitflags 2.10.0", + "serde", + "serde_derive", + "unicode-ident", +] + +[[package]] +name = "ron" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd490c5b18261893f14449cbd28cb9c0b637aebf161cd77900bfdedaff21ec32" +dependencies = [ + "bitflags 2.10.0", + "once_cell", + "serde", + "serde_derive", + "typeid", + "unicode-ident", +] + +[[package]] +name = "route-recognizer" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afab94fb28594581f62d981211a9a4d53cc8130bbcbbb89a0440d9b8e81a7746" + +[[package]] +name = "roxmltree" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97" + +[[package]] +name = "rrs-lib" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4382d3af3a4ebdae7f64ba6edd9114fff92c89808004c4943b393377a25d001" +dependencies = [ + "downcast-rs", + "paste", +] + +[[package]] +name = "rrs-succinct" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3372685893a9f67d18e98e792d690017287fd17379a83d798d958e517d380fa9" +dependencies = [ + "downcast-rs", + "num_enum 0.5.11", + "paste", +] + +[[package]] +name = "rsa" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55a77d189da1fee555ad95b7e50e7457d91c0e089ec68ca69ad2989413bbdab4" +dependencies = [ + "byteorder", + "digest 0.10.7", + "num-bigint-dig", + "num-integer", + "num-iter", + "num-traits", + "pkcs1 0.4.1", + "pkcs8 0.9.0", + "rand_core 0.6.4", + "sha2 0.10.9", + "signature 2.2.0", + "subtle", + "zeroize", +] + +[[package]] +name = "rsa" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40a0376c50d0358279d9d643e4bf7b7be212f1f4ff1da9070a7b54d22ef75c88" +dependencies = [ + "const-oid", + "digest 0.10.7", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1 0.7.5", + "pkcs8 0.10.2", + "rand_core 0.6.4", + "signature 2.2.0", + "spki 0.7.3", + "subtle", + "zeroize", +] + +[[package]] +name = "ruint" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a68df0380e5c9d20ce49534f292a36a7514ae21350726efe1865bdb1fa91d278" +dependencies = [ + "alloy-rlp", + "ark-ff 0.3.0", + "ark-ff 0.4.2", + "ark-ff 0.5.0", + "borsh", + "bytes", + "fastrlp 0.3.1", + "fastrlp 0.4.0", + "num-bigint 0.4.6", + "num-integer", + "num-traits", + "parity-scale-codec 3.7.5", + "primitive-types 0.12.2", + "proptest", + "rand 0.8.5", + "rand 0.9.2", + "rlp", + "ruint-macro", + "serde_core", + "valuable", + "zeroize", +] + +[[package]] +name = "ruint-macro" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" + +[[package]] +name = "runtime" +version = "0.1.0" +dependencies = [ + "async-trait", + "bincode", + "chrono", + "client-blockchain-sui", + "client-bootstrap", + "directories", + "game-content", + "game-core", + "hex", + "memmap2", + "rand 0.8.5", + "ron 0.12.0", + "serde", + "serde_json", + "sha2 0.10.9", + "tempfile", + "thiserror 2.0.17", + "tokio", + "tracing", + "zk", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver 0.11.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver 1.0.27", +] + +[[package]] +name = "rustc_version_runtime" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dd18cd2bae1820af0b6ad5e54f4a51d0f3fcc53b05f845675074efcc7af071d" +dependencies = [ + "rustc_version 0.4.1", + "semver 1.0.27", +] + +[[package]] +name = "rusticata-macros" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" +dependencies = [ + "nom", +] + +[[package]] +name = "rustix" +version = "0.38.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +dependencies = [ + "bitflags 2.10.0", + "errno", + "libc", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustix" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" +dependencies = [ + "bitflags 2.10.0", + "errno", + "libc", + "linux-raw-sys 0.11.0", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls" +version = "0.21.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" +dependencies = [ + "log", + "ring", + "rustls-webpki 0.101.7", + "sct", +] + +[[package]] +name = "rustls" +version = "0.23.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "533f54bc6a7d4f647e46ad909549eda97bf5afc1585190ef692b4286b198bd8f" +dependencies = [ + "aws-lc-rs", + "log", + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki 0.103.8", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-native-certs" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +dependencies = [ + "openssl-probe", + "rustls-pemfile 1.0.4", + "schannel", + "security-framework 2.11.1", +] + +[[package]] +name = "rustls-native-certs" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9980d917ebb0c0536119ba501e90834767bffc3d60641457fd84a1f3fd337923" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework 3.5.1", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.7", +] + +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94182ad936a0c91c324cd46c6511b9510ed16af436d7b5bab34beab0afd55f7a" +dependencies = [ + "web-time", + "zeroize", +] + +[[package]] +name = "rustls-platform-verifier" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19787cda76408ec5404443dc8b31795c87cd8fec49762dc75fa727740d34acc1" +dependencies = [ + "core-foundation 0.10.1", + "core-foundation-sys", + "jni", + "log", + "once_cell", + "rustls 0.23.35", + "rustls-native-certs 0.8.2", + "rustls-platform-verifier-android", + "rustls-webpki 0.103.8", + "security-framework 3.5.1", + "security-framework-sys", + "webpki-root-certs 0.26.11", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustls-platform-verifier-android" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52" +dependencies = [ + "aws-lc-rs", + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "rusty-fork" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc6bf79ff24e648f6da1f8d1f011e9cac26491b619e6b9280f2b47f1774e6ee2" +dependencies = [ + "fnv", + "quick-error", + "tempfile", + "wait-timeout", +] + +[[package]] +name = "rustybuzz" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfb9cf8877777222e4a3bc7eb247e398b56baba500c38c1c46842431adc8b55c" +dependencies = [ + "bitflags 2.10.0", + "bytemuck", + "libm", + "smallvec", + "ttf-parser 0.21.1", + "unicode-bidi-mirroring", + "unicode-ccc", + "unicode-properties", + "unicode-script", +] + +[[package]] +name = "rustyline" +version = "14.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7803e8936da37efd9b6d4478277f4b2b9bb5cdb37a113e8d63222e58da647e63" +dependencies = [ + "bitflags 2.10.0", + "cfg-if", + "clipboard-win", + "fd-lock", + "home", + "libc", + "log", + "memchr", + "nix 0.28.0", + "radix_trie", + "unicode-segmentation", + "unicode-width 0.1.14", + "utf8parse", + "windows-sys 0.52.0", +] + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "rzup" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d2aed296f203fa64bcb4b52069356dd86d6ec578593985b919b6995bee1f0ae" +dependencies = [ + "hex", + "rsa 0.9.9", + "semver 1.0.27", + "serde", + "serde_with", + "sha2 0.10.9", + "strum 0.27.2", + "tempfile", + "thiserror 2.0.17", + "toml 0.8.23", + "yaml-rust2", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scale-info" +version = "2.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "346a3b32eba2640d17a9cb5927056b08f3de90f65b72fe09402c2ad07d684d0b" +dependencies = [ + "cfg-if", + "derive_more 1.0.0", + "parity-scale-codec 3.7.5", + "scale-info-derive", +] + +[[package]] +name = "scale-info-derive" +version = "2.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6630024bf739e2179b91fb424b28898baf819414262c5d376677dbff1fe7ebf" +dependencies = [ + "proc-macro-crate 3.4.0", + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "scc" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46e6f046b7fef48e2660c57ed794263155d713de679057f2d0c169bfc6e756cc" +dependencies = [ + "sdd", +] + +[[package]] +name = "schannel" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "schemafy" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8aea5ba40287dae331f2c48b64dbc8138541f5e97ee8793caa7948c1f31d86d5" +dependencies = [ + "Inflector", + "schemafy_core", + "schemafy_lib", + "serde", + "serde_derive", + "serde_json", + "serde_repr", + "syn 1.0.109", +] + +[[package]] +name = "schemafy_core" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41781ae092f4fd52c9287efb74456aea0d3b90032d2ecad272bd14dbbcb0511b" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "schemafy_lib" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e953db32579999ca98c451d80801b6f6a7ecba6127196c5387ec0774c528befa" +dependencies = [ + "Inflector", + "proc-macro2", + "quote", + "schemafy_core", + "serde", + "serde_derive", + "serde_json", + "syn 1.0.109", +] + +[[package]] +name = "schemars" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615" +dependencies = [ + "dyn-clone", + "either", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9558e172d4e8533736ba97870c4b2cd63f84b382a3d6eb063da41b91cce17289" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e265784ad618884abaea0600a9adf15393368d840e0222d101a072f3f7534d" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 2.0.110", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "sdd" +version = "3.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490dcfcbfef26be6800d11870ff2df8774fa6e86d047e3e8c8a76b25655e41ca" + +[[package]] +name = "sec1" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +dependencies = [ + "base16ct 0.1.1", + "der 0.6.1", + "generic-array 0.14.7", + "subtle", + "zeroize", +] + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct 0.2.0", + "der 0.7.10", + "generic-array 0.14.7", + "pkcs8 0.10.2", + "serdect", + "subtle", + "zeroize", +] + +[[package]] +name = "secp256k1" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f" +dependencies = [ + "bitcoin_hashes 0.12.0", + "rand 0.8.5", + "secp256k1-sys 0.8.2", +] + +[[package]] +name = "secp256k1" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b50c5943d326858130af85e049f2661ba3c78b26589b8ab98e65e80ae44a1252" +dependencies = [ + "bitcoin_hashes 0.14.0", + "rand 0.8.5", + "secp256k1-sys 0.10.1", + "serde", +] + +[[package]] +name = "secp256k1-sys" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4473013577ec77b4ee3668179ef1186df3146e2cf2d927bd200974c6fe60fd99" +dependencies = [ + "cc", +] + +[[package]] +name = "secp256k1-sys" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4387882333d3aa8cb20530a17c69a3752e97837832f34f6dccc760e715001d9" +dependencies = [ + "cc", +] + +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags 2.10.0", + "core-foundation 0.9.4", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework" +version = "3.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" +dependencies = [ + "bitflags 2.10.0", + "core-foundation 0.10.1", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "self_cell" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16c2f82143577edb4921b71ede051dac62ca3c16084e918bf7b40c96ae10eb33" + +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +dependencies = [ + "serde", + "serde_core", +] + +[[package]] +name = "semver-parser" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9900206b54a3527fdc7b8a938bffd94a568bac4f4aa8113b209df75a09c0dec2" +dependencies = [ + "pest", +] + +[[package]] +name = "send_wrapper" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde-big-array" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11fc7cc2c76d73e0f27ee52abbd64eec84d46f370c88371120433196934e4b7f" +dependencies = [ + "serde", +] + +[[package]] +name = "serde-env" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d13536c0c431652192b75c7d5afa83dedae98f91d7e687ff30a009e9d15284fb" +dependencies = [ + "anyhow", + "serde", +] + +[[package]] +name = "serde-name" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b5b14ebbcc4e4f2b3642fa99c388649da58d1dc3308c7d109f39f565d1710f0" +dependencies = [ + "serde", + "thiserror 1.0.69", +] + +[[package]] +name = "serde-reflection" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5bef77b40d103fda6c10d29c21f5c78c980e8570e1a290a648a9ff5011f96e1" +dependencies = [ + "erased-discriminant", + "once_cell", + "serde", + "thiserror 1.0.69", + "typeid", +] + +[[package]] +name = "serde_bytes" +version = "0.11.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8" +dependencies = [ + "serde", + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "serde_derive_internals" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "serde_json" +version = "1.0.145" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +dependencies = [ + "indexmap 2.12.1", + "itoa", + "memchr", + "ryu", + "serde", + "serde_core", +] + +[[package]] +name = "serde_path_to_error" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457" +dependencies = [ + "itoa", + "serde", + "serde_core", +] + +[[package]] +name = "serde_repr" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "serde_spanned" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_spanned" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e24345aa0fe688594e73770a5f6d1b216508b4f93484c0026d521acd30134392" +dependencies = [ + "serde_core", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_with" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10574371d41b0d9b2cff89418eda27da52bcaff2cc8741db26382a77c29131f1" +dependencies = [ + "base64 0.22.1", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.12.1", + "schemars 0.9.0", + "schemars 1.1.0", + "serde_core", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08a72d8216842fdd57820dc78d840bef99248e35fb2554ff923319e60f2d686b" +dependencies = [ + "darling 0.21.3", + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "serde_yaml" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b" +dependencies = [ + "indexmap 1.9.3", + "ryu", + "serde", + "yaml-rust", +] + +[[package]] +name = "serdect" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" +dependencies = [ + "base16ct 0.2.0", + "serde", +] + +[[package]] +name = "serial_test" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b258109f244e1d6891bf1053a55d63a5cd4f8f4c30cf9a1280989f80e7a1fa9" +dependencies = [ + "futures", + "log", + "once_cell", + "parking_lot", + "scc", + "serial_test_derive", +] + +[[package]] +name = "serial_test_derive" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d69265a08751de7844521fd15003ae0a888e035773ba05695c5c759a6f89eef" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "sha3-asm" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28efc5e327c837aa837c59eae585fc250715ef939ac32881bcc11677cd02d46" +dependencies = [ + "cc", + "cfg-if", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shared-crypto" +version = "0.0.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "bcs", + "eyre", + "fastcrypto", + "serde", + "serde_repr", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-mio" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b75a19a7a740b25bc7944bdee6172368f988763b744e3d4dfe753f6b4ece40cc" +dependencies = [ + "libc", + "mio", + "signal-hook", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + +[[package]] +name = "similar" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" + +[[package]] +name = "simple-server-timing-header" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16e78919e05c9b8e123d435a4ad104b488ad1585631830e413830985c214086e" + +[[package]] +name = "siphasher" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" + +[[package]] +name = "size" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fed904c7fb2856d868b92464fc8fa597fce366edea1a9cbfaa8cb5fe080bd6d" + +[[package]] +name = "sized-chunks" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16d69225bde7a69b235da73377861095455d298f2b970996eec25ddbb42b3d1e" +dependencies = [ + "bitmaps", + "typenum", +] + +[[package]] +name = "skrifa" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1c44ad1f6c5bdd4eefed8326711b7dbda9ea45dfd36068c427d332aa382cbe" +dependencies = [ + "bytemuck", + "read-fonts", +] + +[[package]] +name = "slab" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" + +[[package]] +name = "slip10_ed25519" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be0ff28bf14f9610a342169084e87a4f435ad798ec528dc7579a3678fa9dc9a" +dependencies = [ + "hmac-sha512", +] + +[[package]] +name = "slotmap" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" +dependencies = [ + "version_check", +] + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +dependencies = [ + "serde", +] + +[[package]] +name = "smol_str" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" +dependencies = [ + "serde", +] + +[[package]] +name = "snafu" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e84b3f4eacbf3a1ce05eac6763b4d629d60cbc94d632e4092c54ade71f1e1a2" +dependencies = [ + "snafu-derive", +] + +[[package]] +name = "snafu-derive" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1c97747dbf44bb1ca44a561ece23508e99cb592e862f22222dcf42f51d1e451" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "snap" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b6b67fb9a61334225b5b790716f609cd58395f895b3fe8b328786812a40bc3b" + +[[package]] +name = "snowbridge-amcl" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460a9ed63cdf03c1b9847e8a12a5f5ba19c4efd5869e4a737e05be25d7c427e5" +dependencies = [ + "parity-scale-codec 3.7.5", + "scale-info", +] + +[[package]] +name = "socket2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "socket2" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +dependencies = [ + "libc", + "windows-sys 0.60.2", +] + +[[package]] +name = "soketto" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e859df029d160cb88608f5d7df7fb4753fd20fdfb4de5644f3d8b8440841721" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures", + "http 1.3.1", + "httparse", + "log", + "rand 0.8.5", + "sha1", +] + +[[package]] +name = "sp1-build" +version = "5.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7bcc9e463a19749f6080f69ee6410aadda0576115d60bed68d2ebc2d8af3fe4" +dependencies = [ + "anyhow", + "cargo_metadata 0.18.1", + "chrono", + "clap", + "dirs 5.0.1", + "sp1-prover", +] + +[[package]] +name = "sp1-core-executor" +version = "5.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb8bc70057a88164e479e367e2f83f7e7fba52d66acfbeef3b2174dc98c3627" +dependencies = [ + "bincode", + "bytemuck", + "clap", + "elf", + "enum-map", + "eyre", + "hashbrown 0.14.5", + "hex", + "itertools 0.13.0", + "nohash-hasher", + "num", + "p3-baby-bear", + "p3-field", + "p3-maybe-rayon", + "p3-util", + "rand 0.8.5", + "range-set-blaze", + "rrs-succinct", + "serde", + "serde_json", + "sp1-curves", + "sp1-primitives", + "sp1-stark", + "strum 0.26.3", + "strum_macros 0.26.4", + "subenum", + "thiserror 1.0.69", + "tiny-keccak", + "tracing", + "typenum", + "vec_map", +] + +[[package]] +name = "sp1-core-machine" +version = "5.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe446bea36feb189af83cda6ea5420150e877764e2ed4ab4cb2ee5cd3e20355c" +dependencies = [ + "bincode", + "cbindgen", + "cc", + "cfg-if", + "elliptic-curve 0.13.8", + "generic-array 1.1.0", + "glob", + "hashbrown 0.14.5", + "hex", + "itertools 0.13.0", + "k256 0.13.4", + "num", + "num_cpus", + "p256", + "p3-air", + "p3-baby-bear", + "p3-challenger", + "p3-field", + "p3-keccak-air", + "p3-matrix", + "p3-maybe-rayon", + "p3-poseidon2", + "p3-symmetric", + "p3-uni-stark", + "p3-util", + "pathdiff", + "rand 0.8.5", + "rayon", + "rayon-scan", + "serde", + "serde_json", + "size", + "snowbridge-amcl", + "sp1-core-executor", + "sp1-curves", + "sp1-derive", + "sp1-primitives", + "sp1-stark", + "static_assertions", + "strum 0.26.3", + "strum_macros 0.26.4", + "tempfile", + "thiserror 1.0.69", + "tracing", + "tracing-forest", + "tracing-subscriber 0.3.20", + "typenum", + "web-time", +] + +[[package]] +name = "sp1-cuda" +version = "5.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae79f89725c6e21dadb62be31a1c218292f5489559a848faf533419c722a3b3b" +dependencies = [ + "bincode", + "ctrlc", + "prost 0.13.5", + "serde", + "sp1-core-machine", + "sp1-prover", + "tokio", + "tracing", + "twirp-rs", +] + +[[package]] +name = "sp1-curves" +version = "5.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a7ce14c504360349f3eda564a0c9de286c35e1dfbcc979921a3384db02ae82" +dependencies = [ + "cfg-if", + "dashu", + "elliptic-curve 0.13.8", + "generic-array 1.1.0", + "itertools 0.13.0", + "k256 0.13.4", + "num", + "p256", + "p3-field", + "serde", + "snowbridge-amcl", + "sp1-primitives", + "sp1-stark", + "typenum", +] + +[[package]] +name = "sp1-derive" +version = "5.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1144840e0b75e988f3b8d24ffd015bc5fd76599f7864bfd994f3eaf2eb261a" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "sp1-lib" +version = "5.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb1a9935d58cb1dcd757a1b10d727090f5b718f1f03b512d48f0c1952e6ead00" +dependencies = [ + "bincode", + "elliptic-curve 0.13.8", + "serde", + "sp1-primitives", +] + +[[package]] +name = "sp1-primitives" +version = "5.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7d2a6187e394c30097ea7a975a4832f172918690dc89a979f0fad67422d3a8b" +dependencies = [ + "bincode", + "blake3", + "cfg-if", + "hex", + "lazy_static", + "num-bigint 0.4.6", + "p3-baby-bear", + "p3-field", + "p3-poseidon2", + "p3-symmetric", + "serde", + "sha2 0.10.9", +] + +[[package]] +name = "sp1-prover" +version = "5.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfc62e3139fdb1671067987f78ca85a24ea34dbc2f61dbbe3f92b9739e7aa2b9" +dependencies = [ + "anyhow", + "bincode", + "clap", + "dirs 5.0.1", + "downloader", + "enum-map", + "eyre", + "hashbrown 0.14.5", + "hex", + "itertools 0.13.0", + "lru 0.12.5", + "num-bigint 0.4.6", + "p3-baby-bear", + "p3-bn254-fr", + "p3-challenger", + "p3-commit", + "p3-field", + "p3-matrix", + "p3-symmetric", + "p3-util", + "rayon", + "serde", + "serde_json", + "serial_test", + "sha2 0.10.9", + "sp1-core-executor", + "sp1-core-machine", + "sp1-primitives", + "sp1-recursion-circuit", + "sp1-recursion-compiler", + "sp1-recursion-core", + "sp1-recursion-gnark-ffi", + "sp1-stark", + "sp1-verifier", + "thiserror 1.0.69", + "tracing", + "tracing-appender", + "tracing-subscriber 0.3.20", +] + +[[package]] +name = "sp1-recursion-circuit" +version = "5.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44f16af7722bb0f7adabbfc0e60b7fe71ca546959d251c450afb79daaa589c56" +dependencies = [ + "hashbrown 0.14.5", + "itertools 0.13.0", + "num-traits", + "p3-air", + "p3-baby-bear", + "p3-bn254-fr", + "p3-challenger", + "p3-commit", + "p3-dft", + "p3-field", + "p3-fri", + "p3-matrix", + "p3-symmetric", + "p3-uni-stark", + "p3-util", + "rand 0.8.5", + "rayon", + "serde", + "sp1-core-executor", + "sp1-core-machine", + "sp1-derive", + "sp1-primitives", + "sp1-recursion-compiler", + "sp1-recursion-core", + "sp1-recursion-gnark-ffi", + "sp1-stark", + "tracing", +] + +[[package]] +name = "sp1-recursion-compiler" +version = "5.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c83564beb23361e0b93d64f3b8d4a503eac8ced246648f727d44b0827165014" +dependencies = [ + "backtrace", + "itertools 0.13.0", + "p3-baby-bear", + "p3-bn254-fr", + "p3-field", + "p3-symmetric", + "serde", + "sp1-core-machine", + "sp1-primitives", + "sp1-recursion-core", + "sp1-recursion-derive", + "sp1-stark", + "tracing", + "vec_map", +] + +[[package]] +name = "sp1-recursion-core" +version = "5.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c209fa6e384ff56ea7761ccc65426da08516d72ae55b6d8e4021b58bd4022f8" +dependencies = [ + "backtrace", + "cbindgen", + "cc", + "cfg-if", + "ff 0.13.1", + "glob", + "hashbrown 0.14.5", + "itertools 0.13.0", + "num_cpus", + "p3-air", + "p3-baby-bear", + "p3-bn254-fr", + "p3-challenger", + "p3-commit", + "p3-dft", + "p3-field", + "p3-fri", + "p3-matrix", + "p3-maybe-rayon", + "p3-merkle-tree", + "p3-poseidon2", + "p3-symmetric", + "p3-util", + "pathdiff", + "rand 0.8.5", + "serde", + "sp1-core-machine", + "sp1-derive", + "sp1-primitives", + "sp1-stark", + "static_assertions", + "thiserror 1.0.69", + "tracing", + "vec_map", + "zkhash", +] + +[[package]] +name = "sp1-recursion-derive" +version = "5.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8ca2e82fea312a406f4ad4cba1a11812da4cea806607c56ec1670fd55b2ea6" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "sp1-recursion-gnark-ffi" +version = "5.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e146d24ce91c08e36b270a73de9817b9847e759a3d66923b009c67f24a3b9b2" +dependencies = [ + "anyhow", + "bincode", + "bindgen 0.70.1", + "cc", + "cfg-if", + "hex", + "num-bigint 0.4.6", + "p3-baby-bear", + "p3-field", + "p3-symmetric", + "serde", + "serde_json", + "sha2 0.10.9", + "sp1-core-machine", + "sp1-recursion-compiler", + "sp1-stark", + "tempfile", + "tracing", +] + +[[package]] +name = "sp1-sdk" +version = "5.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9655067dcadba91f01491729cc78a60ad3a5ffaaf9adab817502f729ddb3761" +dependencies = [ + "alloy-primitives", + "alloy-signer", + "alloy-signer-aws", + "alloy-signer-local", + "alloy-sol-types", + "anyhow", + "async-trait", + "aws-config", + "aws-sdk-kms", + "backoff", + "bincode", + "cfg-if", + "dirs 5.0.1", + "eventsource-stream", + "futures", + "hashbrown 0.14.5", + "hex", + "indicatif", + "itertools 0.13.0", + "k256 0.13.4", + "p3-baby-bear", + "p3-field", + "p3-fri", + "prost 0.13.5", + "reqwest 0.12.24", + "reqwest-middleware", + "rustls 0.23.35", + "serde", + "serde_json", + "sp1-build", + "sp1-core-executor", + "sp1-core-machine", + "sp1-cuda", + "sp1-primitives", + "sp1-prover", + "sp1-stark", + "strum 0.26.3", + "strum_macros 0.26.4", + "sysinfo", + "tempfile", + "thiserror 1.0.69", + "tokio", + "tonic 0.12.3", + "tracing", + "twirp-rs", +] + +[[package]] +name = "sp1-stark" +version = "5.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40477690a0bb6d7102322947407439a8f1d05aecd535f0081db05e9a31f808f2" +dependencies = [ + "arrayref", + "hashbrown 0.14.5", + "itertools 0.13.0", + "num-bigint 0.4.6", + "num-traits", + "p3-air", + "p3-baby-bear", + "p3-challenger", + "p3-commit", + "p3-dft", + "p3-field", + "p3-fri", + "p3-matrix", + "p3-maybe-rayon", + "p3-merkle-tree", + "p3-poseidon2", + "p3-symmetric", + "p3-uni-stark", + "p3-util", + "rayon-scan", + "serde", + "sp1-derive", + "sp1-primitives", + "strum 0.26.3", + "sysinfo", + "tracing", +] + +[[package]] +name = "sp1-sui" +version = "0.1.0" +source = "git+https://github.com/SoundnessLabs/sp1-sui#15d84fd54f8127c4a5c5fac6fad75eb888d46fa2" +dependencies = [ + "ark-bn254 0.5.0", + "ark-ec 0.5.0", + "ark-ff 0.5.0", + "ark-groth16 0.5.0", + "ark-serialize 0.5.0", + "ark-snark 0.5.1", + "clap", + "hex", + "num-bigint 0.4.6", + "num-traits", + "sp1-sdk", + "sp1-verifier", + "thiserror 2.0.17", +] + +[[package]] +name = "sp1-verifier" +version = "5.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f95bd323fde5d19116873b29e5f8e20da371466d70185732bbfd3511ca0fd31" +dependencies = [ + "blake3", + "cfg-if", + "hex", + "lazy_static", + "sha2 0.10.9", + "substrate-bn-succinct", + "thiserror 2.0.17", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "spinning_top" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d96d2d1d716fb500937168cc09353ffdc7a012be8475ac7308e1bdf0e3923300" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spirv" +version = "0.3.0+sdk-1.3.268.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" +dependencies = [ + "bitflags 2.10.0", +] + +[[package]] +name = "spki" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +dependencies = [ + "base64ct", + "der 0.6.1", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der 0.7.10", +] + +[[package]] +name = "stability" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d904e7009df136af5297832a3ace3370cd14ff1546a232f4f185036c2736fcac" +dependencies = [ + "quote", + "syn 2.0.110", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "stacker" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1f8b29fb42aafcea4edeeb6b2f2d7ecd0d969c48b4cf0d2e64aafc471dd6e59" +dependencies = [ + "cc", + "cfg-if", + "libc", + "psm", + "windows-sys 0.59.0", +] + +[[package]] +name = "stackfuture" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115beb9c69db2393ff10b75a1b8587a51716e5551d015001e55320ed279d32f9" +dependencies = [ + "const_panic", +] + +[[package]] +name = "starlark" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f53849859f05d9db705b221bd92eede93877fd426c1b4a3c3061403a5912a8f" +dependencies = [ + "allocative", + "anyhow", + "bumpalo", + "cmp_any", + "debugserver-types", + "derivative", + "derive_more 1.0.0", + "display_container", + "dupe", + "either", + "erased-serde 0.3.31", + "hashbrown 0.14.5", + "inventory", + "itertools 0.13.0", + "maplit", + "memoffset", + "num-bigint 0.4.6", + "num-traits", + "once_cell", + "paste", + "ref-cast", + "regex", + "rustyline", + "serde", + "serde_json", + "starlark_derive", + "starlark_map", + "starlark_syntax", + "static_assertions", + "strsim 0.10.0", + "textwrap", + "thiserror 1.0.69", +] + +[[package]] +name = "starlark_derive" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe58bc6c8b7980a1fe4c9f8f48200c3212db42ebfe21ae6a0336385ab53f082a" +dependencies = [ + "dupe", + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "starlark_map" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92659970f120df0cc1c0bb220b33587b7a9a90e80d4eecc5c5af5debb950173d" +dependencies = [ + "allocative", + "dupe", + "equivalent", + "fxhash", + "hashbrown 0.14.5", + "serde", +] + +[[package]] +name = "starlark_syntax" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe53b3690d776aafd7cb6b9fed62d94f83280e3b87d88e3719cc0024638461b3" +dependencies = [ + "allocative", + "annotate-snippets", + "anyhow", + "derivative", + "derive_more 1.0.0", + "dupe", + "lalrpop", + "lalrpop-util", + "logos", + "lsp-types 0.94.1", + "memchr", + "num-bigint 0.4.6", + "num-traits", + "once_cell", + "starlark_map", + "thiserror 1.0.69", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "string_cache" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" +dependencies = [ + "new_debug_unreachable", + "parking_lot", + "phf_shared", + "precomputed-hash", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +dependencies = [ + "strum_macros 0.25.3", +] + +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros 0.26.4", +] + +[[package]] +name = "strum" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" +dependencies = [ + "strum_macros 0.27.2", +] + +[[package]] +name = "strum_macros" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.110", +] + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.110", +] + +[[package]] +name = "strum_macros" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "subenum" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3d08fe7078c57309d5c3d938e50eba95ba1d33b9c3a101a8465fc6861a5416" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "substrate-bn-succinct" +version = "0.6.0-v5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ba32f1b74728f92887c3ad17c42bf82998eb52c9091018f35294e9cd388b0c8" +dependencies = [ + "bytemuck", + "byteorder", + "cfg-if", + "crunchy", + "lazy_static", + "num-bigint 0.4.6", + "rand 0.8.5", + "rustc-hex", + "sp1-lib", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "subtle-ng" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" + +[[package]] +name = "sui-config" +version = "0.0.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "anemo", + "anyhow", + "bcs", + "clap", + "consensus-config", + "csv", + "dirs 4.0.0", + "fastcrypto", + "move-vm-config", + "mysten-common", + "nonzero_ext", + "object_store", + "once_cell", + "prometheus", + "rand 0.8.5", + "reqwest 0.12.24", + "serde", + "serde_json", + "serde_with", + "serde_yaml", + "starlark", + "sui-keys", + "sui-protocol-config", + "sui-types", + "thiserror 1.0.69", + "tracing", +] + +[[package]] +name = "sui-enum-compat-util" +version = "0.1.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "serde_yaml", +] + +[[package]] +name = "sui-http" +version = "0.0.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "bytes", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "hyper 1.8.1", + "hyper-util", + "pin-project-lite", + "socket2 0.5.10", + "tokio", + "tokio-rustls 0.26.4", + "tokio-util", + "tower 0.5.2", + "tracing", +] + +[[package]] +name = "sui-json" +version = "0.0.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "anyhow", + "bcs", + "fastcrypto", + "move-binary-format", + "move-bytecode-utils", + "move-core-types", + "schemars 0.8.22", + "serde", + "serde_json", + "sui-types", +] + +[[package]] +name = "sui-json-rpc-api" +version = "0.0.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "anyhow", + "fastcrypto", + "jsonrpsee", + "mysten-metrics", + "once_cell", + "prometheus", + "sui-json", + "sui-json-rpc-types", + "sui-open-rpc", + "sui-open-rpc-macros", + "sui-types", + "tap", + "tracing", +] + +[[package]] +name = "sui-json-rpc-types" +version = "0.0.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "anyhow", + "bcs", + "colored", + "enum_dispatch", + "fastcrypto", + "itertools 0.13.0", + "json_to_table", + "move-binary-format", + "move-bytecode-utils", + "move-command-line-common", + "move-core-types", + "move-disassembler", + "move-ir-types", + "mysten-metrics", + "nonempty", + "schemars 0.8.22", + "serde", + "serde_json", + "serde_with", + "sui-enum-compat-util", + "sui-json", + "sui-macros", + "sui-package-resolver", + "sui-protocol-config", + "sui-types", + "tabled", + "tracing", +] + +[[package]] +name = "sui-keys" +version = "0.0.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "anyhow", + "async-trait", + "base64 0.21.7", + "bcs", + "bip32", + "colored", + "fastcrypto", + "jsonrpc", + "mockall", + "rand 0.8.5", + "regex", + "serde", + "serde_json", + "shared-crypto", + "signature 1.6.4", + "slip10_ed25519", + "sui-types", + "tiny-bip39", + "tokio", +] + +[[package]] +name = "sui-macros" +version = "0.7.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "futures", + "once_cell", + "sui-proc-macros", + "tracing", +] + +[[package]] +name = "sui-open-rpc" +version = "1.62.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "bcs", + "schemars 0.8.22", + "serde", + "serde_json", + "versions", +] + +[[package]] +name = "sui-open-rpc-macros" +version = "0.1.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "derive-syn-parse", + "itertools 0.13.0", + "proc-macro2", + "quote", + "syn 1.0.109", + "unescape", +] + +[[package]] +name = "sui-package-resolver" +version = "0.1.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "async-trait", + "bcs", + "eyre", + "lru 0.10.1", + "move-binary-format", + "move-command-line-common", + "move-core-types", + "serde", + "sui-types", + "thiserror 1.0.69", + "tokio", +] + +[[package]] +name = "sui-proc-macros" +version = "0.7.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "msim-macros", + "proc-macro2", + "quote", + "sui-enum-compat-util", + "syn 2.0.110", +] + +[[package]] +name = "sui-protocol-config" +version = "0.1.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "clap", + "fastcrypto", + "move-binary-format", + "move-core-types", + "move-vm-config", + "schemars 0.8.22", + "serde", + "serde-env", + "serde_with", + "sui-protocol-config-macros", + "tracing", +] + +[[package]] +name = "sui-protocol-config-macros" +version = "0.1.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "sui-rpc" +version = "0.0.8" +source = "git+https://github.com/MystenLabs/sui-rust-sdk.git?rev=fb62af78b30f5dc64eeaec0094ab95b5ce5b7ce2#fb62af78b30f5dc64eeaec0094ab95b5ce5b7ce2" +dependencies = [ + "base64 0.22.1", + "bcs", + "bytes", + "futures", + "http 1.3.1", + "prost 0.14.1", + "prost-types", + "serde", + "serde_json", + "sui-sdk-types", + "tap", + "tokio", + "tonic 0.14.2", + "tonic-prost", +] + +[[package]] +name = "sui-sdk" +version = "1.62.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "anyhow", + "async-trait", + "base64 0.21.7", + "bcs", + "clap", + "colored", + "fastcrypto", + "futures", + "futures-core", + "jsonrpsee", + "move-core-types", + "reqwest 0.12.24", + "serde", + "serde_json", + "serde_with", + "shared-crypto", + "sui-config", + "sui-json", + "sui-json-rpc-api", + "sui-json-rpc-types", + "sui-keys", + "sui-transaction-builder", + "sui-types", + "thiserror 1.0.69", + "tokio", + "tracing", +] + +[[package]] +name = "sui-sdk-types" +version = "0.0.8" +source = "git+https://github.com/MystenLabs/sui-rust-sdk.git?rev=fb62af78b30f5dc64eeaec0094ab95b5ce5b7ce2#fb62af78b30f5dc64eeaec0094ab95b5ce5b7ce2" +dependencies = [ + "base64ct", + "bcs", + "blake2", + "bnum", + "bs58 0.5.1", + "bytes", + "bytestring", + "itertools 0.14.0", + "roaring 0.11.2", + "serde", + "serde_derive", + "serde_json", + "serde_with", + "winnow", +] + +[[package]] +name = "sui-transaction-builder" +version = "0.0.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "anyhow", + "async-trait", + "bcs", + "futures", + "move-binary-format", + "move-core-types", + "sui-json", + "sui-json-rpc-types", + "sui-protocol-config", + "sui-types", +] + +[[package]] +name = "sui-types" +version = "0.1.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" +dependencies = [ + "anemo", + "anyhow", + "async-trait", + "base64 0.21.7", + "bcs", + "better_any", + "bincode", + "byteorder", + "bytes", + "chrono", + "ciborium", + "consensus-config", + "consensus-types", + "derive_more 1.0.0", + "enum_dispatch", + "eyre", + "fastcrypto", + "fastcrypto-tbls", + "fastcrypto-zkp", + "im", + "indexmap 2.12.1", + "itertools 0.13.0", + "lru 0.10.1", + "move-binary-format", + "move-bytecode-utils", + "move-core-types", + "move-trace-format", + "move-vm-profiler", + "move-vm-test-utils", + "mysten-common", + "mysten-metrics", + "mysten-network", + "nonempty", + "num-bigint 0.4.6", + "num-traits", + "num_enum 0.6.1", + "once_cell", + "p384", + "parking_lot", + "passkey-types", + "prometheus", + "proptest", + "proptest-derive", + "prost 0.14.1", + "prost-types", + "rand 0.8.5", + "roaring 0.10.12", + "rustls-pemfile 2.2.0", + "schemars 0.8.22", + "serde", + "serde-name", + "serde_json", + "serde_with", + "shared-crypto", + "signature 1.6.4", + "static_assertions", + "strum 0.27.2", + "strum_macros 0.27.2", + "sui-enum-compat-util", + "sui-macros", + "sui-protocol-config", + "sui-rpc", + "sui-sdk-types", + "tap", + "thiserror 1.0.69", + "tonic 0.14.2", + "tracing", + "typed-store-error", + "x509-parser", +] + +[[package]] +name = "svg_fmt" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0193cc4331cfd2f3d2011ef287590868599a2f33c3e69bc22c1a3d3acf9e02fb" + +[[package]] +name = "swash" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbd59f3f359ddd2c95af4758c18270eddd9c730dde98598023cdabff472c2ca2" +dependencies = [ + "skrifa", + "yazi", + "zeno", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.110" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a99801b5bd34ede4cf3fc688c5919368fea4e4814a4664359503e6015b280aea" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn-solidity" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff790eb176cc81bb8936aed0f7b9f14fc4670069a2d371b3e3b0ecce908b2cb3" +dependencies = [ + "paste", + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "unicode-xid", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "sys-locale" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eab9a99a024a169fe8a903cf9d4a3b3601109bcc13bd9e3c6fff259138626c4" +dependencies = [ + "libc", +] + +[[package]] +name = "sysinfo" +version = "0.30.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a5b4ddaee55fb2bea2bf0e5000747e5f5c0de765e5a5ff87f4cd106439f4bb3" +dependencies = [ + "cfg-if", + "core-foundation-sys", + "libc", + "ntapi", + "once_cell", + "rayon", + "windows 0.52.0", ] [[package]] -name = "rustversion" -version = "1.0.22" +name = "system-configuration" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation 0.9.4", + "system-configuration-sys", +] [[package]] -name = "ryu" -version = "1.0.20" +name = "system-configuration-sys" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] [[package]] -name = "rzup" -version = "0.5.1" +name = "tabled" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d2aed296f203fa64bcb4b52069356dd86d6ec578593985b919b6995bee1f0ae" +checksum = "0ce69a5028cd9576063ec1f48edb2c75339fd835e6094ef3e05b3a079bf594a6" dependencies = [ - "hex", - "rsa", - "semver", - "serde", - "serde_with", - "sha2", - "strum 0.27.2", - "tempfile", - "thiserror 2.0.17", - "toml 0.8.23", - "yaml-rust2", + "papergrid", + "tabled_derive", + "unicode-width 0.1.14", ] [[package]] -name = "schemars" -version = "0.9.0" +name = "tabled_derive" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" +checksum = "99f688a08b54f4f02f0a3c382aefdb7884d3d69609f785bd253dc033243e3fe4" dependencies = [ - "dyn-clone", - "ref-cast", - "serde", - "serde_json", + "heck 0.4.1", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] -name = "schemars" -version = "1.0.4" +name = "taffy" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82d20c4491bc164fa2f6c5d44565947a52ad80b9505d8e36f8d54c27c739fcd0" +checksum = "9cb893bff0f80ae17d3a57e030622a967b8dbc90e38284d9b4b1442e23873c94" dependencies = [ - "dyn-clone", - "ref-cast", + "arrayvec", + "grid", + "num-traits", "serde", - "serde_json", + "slotmap", ] [[package]] -name = "scopeguard" -version = "1.2.0" +name = "tap" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] -name = "semver" -version = "1.0.27" +name = "tempfile" +version = "3.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" dependencies = [ - "serde", - "serde_core", + "fastrand", + "getrandom 0.3.4", + "once_cell", + "rustix 1.1.2", + "windows-sys 0.61.2", ] [[package]] -name = "serde" -version = "1.0.228" +name = "term" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" dependencies = [ - "serde_core", - "serde_derive", + "dirs-next", + "rustversion", + "winapi", ] [[package]] -name = "serde_core" -version = "1.0.228" +name = "termcolor" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ - "serde_derive", + "winapi-util", ] [[package]] -name = "serde_derive" -version = "1.0.228" +name = "terminal_size" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +checksum = "60b8cb979cb11c32ce1603f8137b22262a9d131aaa5c37b5678025f22b8becd0" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.108", + "rustix 1.1.2", + "windows-sys 0.60.2", ] [[package]] -name = "serde_json" -version = "1.0.145" +name = "termtree" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" -dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", - "serde_core", -] +checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" [[package]] -name = "serde_spanned" -version = "0.6.9" +name = "textwrap" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" dependencies = [ - "serde", + "unicode-width 0.1.14", ] [[package]] -name = "serde_spanned" -version = "1.0.3" +name = "thiserror" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e24345aa0fe688594e73770a5f6d1b216508b4f93484c0026d521acd30134392" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "serde_core", + "thiserror-impl 1.0.69", ] [[package]] -name = "serde_urlencoded" -version = "0.7.1" +name = "thiserror" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", + "thiserror-impl 2.0.17", ] [[package]] -name = "serde_with" -version = "3.15.1" +name = "thiserror-impl" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa66c845eee442168b2c8134fec70ac50dc20e760769c8ba0ad1319ca1959b04" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ - "base64", - "chrono", - "hex", - "indexmap 1.9.3", - "indexmap 2.12.0", - "schemars 0.9.0", - "schemars 1.0.4", - "serde_core", - "serde_json", - "serde_with_macros", - "time", + "proc-macro2", + "quote", + "syn 2.0.110", ] [[package]] -name = "serde_with_macros" -version = "3.15.1" +name = "thiserror-impl" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91a903660542fced4e99881aa481bdbaec1634568ee02e0b8bd57c64cb38955" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ - "darling 0.21.3", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] -name = "sha2" -version = "0.10.9" +name = "thread_local" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" dependencies = [ "cfg-if", - "cpufeatures", - "digest", ] [[package]] -name = "sharded-slab" -version = "0.1.7" +name = "threadpool" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" dependencies = [ - "lazy_static", + "num_cpus", ] [[package]] -name = "shlex" -version = "1.3.0" +name = "time" +version = "0.3.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] [[package]] -name = "signal-hook" -version = "0.3.18" +name = "time-core" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2" +checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" + +[[package]] +name = "time-macros" +version = "0.2.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" dependencies = [ - "libc", - "signal-hook-registry", + "num-conv", + "time-core", ] [[package]] -name = "signal-hook-mio" -version = "0.2.4" +name = "tiny-bip39" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" +checksum = "62cc94d358b5a1e84a5cb9109f559aa3c4d634d2b1b4de3d0fa4adc7c78e2861" dependencies = [ - "libc", - "mio", - "signal-hook", + "anyhow", + "hmac", + "once_cell", + "pbkdf2", + "rand 0.8.5", + "rustc-hash 1.1.0", + "sha2 0.10.9", + "thiserror 1.0.69", + "unicode-normalization", + "wasm-bindgen", + "zeroize", ] [[package]] -name = "signal-hook-registry" -version = "1.4.6" +name = "tiny-keccak" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" dependencies = [ - "libc", + "crunchy", ] [[package]] -name = "signature" -version = "2.2.0" +name = "tinystr" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" dependencies = [ - "digest", - "rand_core 0.6.4", + "displaydoc", + "zerovec", ] [[package]] -name = "slab" -version = "0.4.11" +name = "tinyvec" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" +checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +dependencies = [ + "tinyvec_macros", +] [[package]] -name = "smallvec" -version = "1.15.1" +name = "tinyvec_macros" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] -name = "socket2" -version = "0.6.1" +name = "tokio" +version = "1.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" dependencies = [ + "bytes", "libc", - "windows-sys 0.60.2", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2 0.6.1", + "tokio-macros", + "windows-sys 0.61.2", ] [[package]] -name = "spin" -version = "0.9.8" +name = "tokio-macros" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", +] [[package]] -name = "spki" -version = "0.7.3" +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "base64ct", - "der", + "rustls 0.21.12", + "tokio", ] [[package]] -name = "stability" -version = "0.2.1" +name = "tokio-rustls" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d904e7009df136af5297832a3ace3370cd14ff1546a232f4f185036c2736fcac" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ - "quote", - "syn 2.0.108", + "rustls 0.23.35", + "tokio", ] [[package]] -name = "stable_deref_trait" -version = "1.2.1" +name = "tokio-stream" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" +checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", + "tokio-util", +] [[package]] -name = "static_assertions" -version = "1.1.0" +name = "tokio-tungstenite" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +checksum = "d25a406cddcc431a75d3d9afc6a7c0f7428d4891dd973e4d54c56b46127bf857" +dependencies = [ + "futures-util", + "log", + "tokio", + "tungstenite", +] [[package]] -name = "strsim" -version = "0.11.1" +name = "tokio-util" +version = "0.7.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594" +dependencies = [ + "bytes", + "futures-core", + "futures-io", + "futures-sink", + "pin-project-lite", + "tokio", +] [[package]] -name = "strum" -version = "0.26.3" +name = "toml" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" dependencies = [ - "strum_macros 0.26.4", + "serde", ] [[package]] -name = "strum" -version = "0.27.2" +name = "toml" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" dependencies = [ - "strum_macros 0.27.2", + "serde", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", + "toml_edit 0.22.27", ] [[package]] -name = "strum_macros" -version = "0.26.4" +name = "toml" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +checksum = "f0dc8b1fb61449e27716ec0e1bdf0f6b8f3e8f6b05391e8497b8b6d7804ea6d8" dependencies = [ - "heck", - "proc-macro2", - "quote", - "rustversion", - "syn 2.0.108", + "indexmap 2.12.1", + "serde_core", + "serde_spanned 1.0.3", + "toml_datetime 0.7.3", + "toml_parser", + "toml_writer", + "winnow", ] [[package]] -name = "strum_macros" -version = "0.27.2" +name = "toml_datetime" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.108", + "serde", ] [[package]] -name = "subtle" -version = "2.6.1" +name = "toml_datetime" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" +dependencies = [ + "serde_core", +] [[package]] -name = "syn" -version = "1.0.109" +name = "toml_edit" +version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", + "indexmap 2.12.1", + "serde", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", + "toml_write", + "winnow", ] [[package]] -name = "syn" -version = "2.0.108" +name = "toml_edit" +version = "0.23.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da58917d35242480a05c2897064da0a80589a2a0476c9a3f2fdc83b53502e917" +checksum = "6485ef6d0d9b5d0ec17244ff7eb05310113c3f316f2d14200d4de56b3cb98f8d" dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", + "indexmap 2.12.1", + "toml_datetime 0.7.3", + "toml_parser", + "winnow", ] [[package]] -name = "sync_wrapper" -version = "1.0.2" +name = "toml_parser" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" dependencies = [ - "futures-core", + "winnow", ] [[package]] -name = "synstructure" -version = "0.13.2" +name = "toml_write" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" + +[[package]] +name = "toml_writer" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df8b2b54733674ad286d16267dcfc7a71ed5c776e4ac7aa3c3e2561f7c637bf2" + +[[package]] +name = "tonic" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.108", + "async-stream", + "async-trait", + "axum 0.7.9", + "base64 0.22.1", + "bytes", + "h2 0.4.12", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "hyper 1.8.1", + "hyper-timeout", + "hyper-util", + "percent-encoding", + "pin-project", + "prost 0.13.5", + "rustls-native-certs 0.8.2", + "rustls-pemfile 2.2.0", + "socket2 0.5.10", + "tokio", + "tokio-rustls 0.26.4", + "tokio-stream", + "tower 0.4.13", + "tower-layer", + "tower-service", + "tracing", ] [[package]] -name = "tempfile" -version = "3.23.0" +name = "tonic" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" +checksum = "eb7613188ce9f7df5bfe185db26c5814347d110db17920415cf2fbcad85e7203" dependencies = [ - "fastrand", - "getrandom 0.3.4", - "once_cell", - "rustix 1.1.2", - "windows-sys 0.61.2", + "async-trait", + "axum 0.8.7", + "base64 0.22.1", + "bytes", + "h2 0.4.12", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "hyper 1.8.1", + "hyper-timeout", + "hyper-util", + "percent-encoding", + "pin-project", + "socket2 0.6.1", + "sync_wrapper 1.0.2", + "tokio", + "tokio-rustls 0.26.4", + "tokio-stream", + "tower 0.5.2", + "tower-layer", + "tower-service", + "tracing", + "webpki-roots", + "zstd", ] [[package]] -name = "thiserror" -version = "1.0.69" +name = "tonic-health" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +checksum = "2a82868bf299e0a1d2e8dce0dc33a46c02d6f045b2c1f1d6cc8dc3d0bf1812ef" dependencies = [ - "thiserror-impl 1.0.69", + "prost 0.14.1", + "tokio", + "tokio-stream", + "tonic 0.14.2", + "tonic-prost", ] [[package]] -name = "thiserror" -version = "2.0.17" +name = "tonic-prost" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" +checksum = "66bd50ad6ce1252d87ef024b3d64fe4c3cf54a86fb9ef4c631fdd0ded7aeaa67" dependencies = [ - "thiserror-impl 2.0.17", + "bytes", + "prost 0.14.1", + "tonic 0.14.2", ] [[package]] -name = "thiserror-impl" -version = "1.0.69" +name = "tower" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.108", + "futures-core", + "futures-util", + "hdrhistogram", + "indexmap 1.9.3", + "pin-project", + "pin-project-lite", + "rand 0.8.5", + "slab", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", ] [[package]] -name = "thiserror-impl" -version = "2.0.17" +name = "tower" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.108", + "futures-core", + "futures-util", + "hdrhistogram", + "indexmap 2.12.1", + "pin-project-lite", + "slab", + "sync_wrapper 1.0.2", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", ] [[package]] -name = "thread_local" -version = "1.1.9" +name = "tower-http" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" dependencies = [ - "cfg-if", + "async-compression", + "base64 0.21.7", + "bitflags 2.10.0", + "bytes", + "futures-core", + "futures-util", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "http-range-header", + "httpdate", + "iri-string", + "mime", + "mime_guess", + "percent-encoding", + "pin-project-lite", + "tokio", + "tokio-util", + "tower 0.4.13", + "tower-layer", + "tower-service", + "tracing", + "uuid", ] [[package]] -name = "time" -version = "0.3.44" +name = "tower-http" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" +checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" dependencies = [ - "deranged", - "itoa", - "num-conv", - "powerfmt", - "serde", - "time-core", - "time-macros", + "bitflags 2.10.0", + "bytes", + "futures-util", + "http 1.3.1", + "http-body 1.0.1", + "iri-string", + "pin-project-lite", + "tower 0.5.2", + "tower-layer", + "tower-service", ] [[package]] -name = "time-core" -version = "0.1.6" +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] -name = "time-macros" -version = "0.2.24" +name = "tracing" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ - "num-conv", - "time-core", + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", ] [[package]] -name = "tinystr" -version = "0.8.1" +name = "tracing-appender" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" +checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" dependencies = [ - "displaydoc", - "zerovec", + "crossbeam-channel", + "thiserror 1.0.69", + "time", + "tracing-subscriber 0.3.20", ] [[package]] -name = "tinyvec" -version = "1.10.0" +name = "tracing-attributes" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" dependencies = [ - "tinyvec_macros", + "proc-macro2", + "quote", + "syn 2.0.110", ] [[package]] -name = "tinyvec_macros" -version = "0.1.1" +name = "tracing-core" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +dependencies = [ + "once_cell", + "valuable", +] [[package]] -name = "tokio" -version = "1.48.0" +name = "tracing-forest" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" +checksum = "ee40835db14ddd1e3ba414292272eddde9dad04d3d4b65509656414d1c42592f" dependencies = [ - "bytes", - "libc", - "mio", - "parking_lot", - "pin-project-lite", - "signal-hook-registry", - "socket2", - "tokio-macros", - "windows-sys 0.61.2", + "ansi_term", + "smallvec", + "thiserror 1.0.69", + "tracing", + "tracing-subscriber 0.3.20", ] [[package]] -name = "tokio-macros" -version = "2.6.0" +name = "tracing-log" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.108", + "log", + "once_cell", + "tracing-core", ] [[package]] -name = "tokio-rustls" -version = "0.26.4" +name = "tracing-oslog" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +checksum = "528bdd1f0e27b5dd9a4ededf154e824b0532731e4af73bb531de46276e0aab1e" dependencies = [ - "rustls", - "tokio", + "bindgen 0.70.1", + "cc", + "cfg-if", + "once_cell", + "parking_lot", + "tracing-core", + "tracing-subscriber 0.3.20", ] [[package]] -name = "tokio-util" -version = "0.7.16" +name = "tracing-subscriber" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" +checksum = "0e0d2eaa99c3c2e41547cfa109e910a68ea03823cccad4a0525dcbc9b01e8c71" dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", + "tracing-core", ] [[package]] -name = "toml" -version = "0.8.23" +name = "tracing-subscriber" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" dependencies = [ - "serde", - "serde_spanned 0.6.9", - "toml_datetime 0.6.11", - "toml_edit 0.22.27", + "matchers", + "nu-ansi-term", + "once_cell", + "regex-automata", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", ] [[package]] -name = "toml" -version = "0.9.8" +name = "tracing-wasm" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0dc8b1fb61449e27716ec0e1bdf0f6b8f3e8f6b05391e8497b8b6d7804ea6d8" +checksum = "4575c663a174420fa2d78f4108ff68f65bf2fbb7dd89f33749b6e826b3626e07" dependencies = [ - "indexmap 2.12.0", - "serde_core", - "serde_spanned 1.0.3", - "toml_datetime 0.7.3", - "toml_parser", - "toml_writer", - "winnow", + "tracing", + "tracing-subscriber 0.3.20", + "wasm-bindgen", ] [[package]] -name = "toml_datetime" -version = "0.6.11" +name = "trait-set" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +checksum = "b79e2e9c9ab44c6d7c20d5976961b47e8f49ac199154daa514b77cd1ab536625" dependencies = [ - "serde", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] -name = "toml_datetime" -version = "0.7.3" +name = "try-lock" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" -dependencies = [ - "serde_core", -] +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] -name = "toml_edit" -version = "0.22.27" +name = "ttf-parser" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +checksum = "17f77d76d837a7830fe1d4f12b7b4ba4192c1888001c7164257e4bc6d21d96b4" + +[[package]] +name = "ttf-parser" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c591d83f69777866b9126b24c6dd9a18351f177e49d625920d19f989fd31cf8" + +[[package]] +name = "tungstenite" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8628dcc84e5a09eb3d8423d6cb682965dea9133204e8fb3efee74c2a0c259442" dependencies = [ - "indexmap 2.12.0", - "serde", - "serde_spanned 0.6.9", - "toml_datetime 0.6.11", - "toml_write", - "winnow", + "bytes", + "data-encoding", + "http 1.3.1", + "httparse", + "log", + "rand 0.9.2", + "sha1", + "thiserror 2.0.17", + "utf-8", ] [[package]] -name = "toml_edit" -version = "0.23.7" +name = "twirp-rs" +version = "0.13.0-succinct" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6485ef6d0d9b5d0ec17244ff7eb05310113c3f316f2d14200d4de56b3cb98f8d" +checksum = "27dfcc06b8d9262bc2d4b8d1847c56af9971a52dd8a0076876de9db763227d0d" dependencies = [ - "indexmap 2.12.0", - "toml_datetime 0.7.3", - "toml_parser", - "winnow", + "async-trait", + "axum 0.7.9", + "futures", + "http 1.3.1", + "http-body-util", + "hyper 1.8.1", + "prost 0.13.5", + "reqwest 0.12.24", + "serde", + "serde_json", + "thiserror 1.0.69", + "tokio", + "tower 0.5.2", + "url", ] [[package]] -name = "toml_parser" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" +name = "typed-store-error" +version = "0.4.0" +source = "git+https://github.com/mystenlabs/sui#3bbe92e62fe102b9f5fa9cdd37bcf7a3b2df8ee7" dependencies = [ - "winnow", + "serde", + "thiserror 1.0.69", ] [[package]] -name = "toml_write" -version = "0.1.2" +name = "typeid" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" +checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" [[package]] -name = "toml_writer" -version = "1.0.4" +name = "typenum" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df8b2b54733674ad286d16267dcfc7a71ed5c776e4ac7aa3c3e2561f7c637bf2" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] -name = "tower" -version = "0.5.2" +name = "typeshare" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" +checksum = "19be0f411120091e76e13e5a0186d8e2bcc3e7e244afdb70152197f1a8486ceb" dependencies = [ - "futures-core", - "futures-util", - "pin-project-lite", - "sync_wrapper", - "tokio", - "tower-layer", - "tower-service", + "chrono", + "serde", + "serde_json", + "typeshare-annotation", ] [[package]] -name = "tower-http" -version = "0.6.6" +name = "typeshare-annotation" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +checksum = "a615d6c2764852a2e88a4f16e9ce1ea49bb776b5872956309e170d63a042a34f" dependencies = [ - "bitflags 2.10.0", - "bytes", - "futures-util", - "http", - "http-body", - "iri-string", - "pin-project-lite", - "tower", - "tower-layer", - "tower-service", + "quote", + "syn 2.0.110", ] [[package]] -name = "tower-layer" -version = "0.3.3" +name = "typewit" +version = "1.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" +checksum = "f8c1ae7cc0fdb8b842d65d127cb981574b0d2b249b74d1c7a2986863dc134f71" [[package]] -name = "tower-service" -version = "0.3.3" +name = "ucd-trie" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" [[package]] -name = "tracing" -version = "0.1.41" +name = "uint" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" dependencies = [ - "log", - "pin-project-lite", - "tracing-attributes", - "tracing-core", + "byteorder", + "crunchy", + "hex", + "static_assertions", ] [[package]] -name = "tracing-appender" -version = "0.2.3" +name = "unarray" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" -dependencies = [ - "crossbeam-channel", - "thiserror 1.0.69", - "time", - "tracing-subscriber 0.3.20", -] +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + +[[package]] +name = "unescape" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccb97dac3243214f8d8507998906ca3e2e0b900bf9bf4870477f125b82e68f6e" [[package]] -name = "tracing-attributes" -version = "0.1.30" +name = "unicase" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.108", -] +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] -name = "tracing-core" -version = "0.1.34" +name = "unicode-bidi" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" -dependencies = [ - "once_cell", - "valuable", -] +checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" [[package]] -name = "tracing-log" +name = "unicode-bidi-mirroring" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" -dependencies = [ - "log", - "once_cell", - "tracing-core", -] +checksum = "23cb788ffebc92c5948d0e997106233eeb1d8b9512f93f41651f52b6c5f5af86" [[package]] -name = "tracing-subscriber" -version = "0.2.25" +name = "unicode-ccc" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e0d2eaa99c3c2e41547cfa109e910a68ea03823cccad4a0525dcbc9b01e8c71" -dependencies = [ - "tracing-core", -] +checksum = "1df77b101bcc4ea3d78dafc5ad7e4f58ceffe0b2b16bf446aeb50b6cb4157656" [[package]] -name = "tracing-subscriber" -version = "0.3.20" +name = "unicode-ident" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" -dependencies = [ - "matchers", - "nu-ansi-term", - "once_cell", - "regex-automata", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log", -] +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" [[package]] -name = "try-lock" -version = "0.2.5" +name = "unicode-linebreak" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" [[package]] -name = "typenum" -version = "1.19.0" +name = "unicode-normalization" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" +checksum = "5fd4f6878c9cb28d874b009da9e8d183b5abc80117c40bbd187a1fde336be6e8" +dependencies = [ + "tinyvec", +] [[package]] -name = "unarray" +name = "unicode-properties" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" +checksum = "7df058c713841ad818f1dc5d3fd88063241cc61f49f5fbea4b951e8cf5a8d71d" [[package]] -name = "unicode-ident" -version = "1.0.20" +name = "unicode-script" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "462eeb75aeb73aea900253ce739c8e18a67423fadf006037cd3ff27e82748a06" +checksum = "9fb421b350c9aff471779e262955939f565ec18b86c15364e6bdf0d662ca7c1f" [[package]] name = "unicode-segmentation" @@ -3749,6 +14862,22 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + +[[package]] +name = "unsigned-varint" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6889a77d49f1f013504cec6bf97a2c730394adedaeb1deb5ea08949a50541105" + [[package]] name = "untrusted" version = "0.9.0" @@ -3767,6 +14896,18 @@ dependencies = [ "serde", ] +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + [[package]] name = "utf8_iter" version = "1.0.4" @@ -3779,18 +14920,96 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "uuid" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3758f5e68192bb96cc8f9b7e2c2cfdabb435499a28499a42f8f984092adad4b" +dependencies = [ + "getrandom 0.2.16", + "rand 0.8.5", + "serde", +] + [[package]] name = "valuable" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" +[[package]] +name = "variant_count" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1935e10c6f04d22688d07c0790f2fc0e1b1c5c2c55bc0cc87ed67656e587dd8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", +] + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" +dependencies = [ + "serde", +] + [[package]] name = "version_check" version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "versions" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee97e1d97bd593fb513912a07691b742361b3dd64ad56f2c694ea2dbfe0665d3" +dependencies = [ + "itertools 0.10.5", + "nom", +] + +[[package]] +name = "vfs" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e4fe92cfc1bad19c19925d5eee4b30584dbbdee4ff10183b261acccbef74e2d" + +[[package]] +name = "vsimd" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" + +[[package]] +name = "wait-timeout" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11" +dependencies = [ + "libc", +] + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "want" version = "0.3.1" @@ -3817,9 +15036,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.104" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d" +checksum = "da95793dfc411fbbd93f5be7715b0578ec61fe87cb1a42b12eb625caa5c5ea60" dependencies = [ "cfg-if", "once_cell", @@ -3828,25 +15047,11 @@ dependencies = [ "wasm-bindgen-shared", ] -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.104" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn 2.0.108", - "wasm-bindgen-shared", -] - [[package]] name = "wasm-bindgen-futures" -version = "0.4.54" +version = "0.4.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e038d41e478cc73bae0ff9b36c60cff1c98b8f38f8d7e8061e79ee63608ac5c" +checksum = "551f88106c6d5e7ccc7cd9a16f312dd3b5d36ea8b4954304657d5dfba115d4a0" dependencies = [ "cfg-if", "js-sys", @@ -3857,9 +15062,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.104" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119" +checksum = "04264334509e04a7bf8690f2384ef5265f05143a4bff3889ab7a3269adab59c2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3867,22 +15072,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.104" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7" +checksum = "420bc339d9f322e562942d52e115d57e950d12d88983a14c79b86859ee6c7ebc" dependencies = [ + "bumpalo", "proc-macro2", "quote", - "syn 2.0.108", - "wasm-bindgen-backend", + "syn 2.0.110", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.104" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1" +checksum = "76f218a38c84bcb33c25ec7059b07847d465ce0e0a76b995e134a45adcb6af76" dependencies = [ "unicode-ident", ] @@ -3902,9 +15107,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.81" +version = "0.3.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9367c417a924a74cae129e6a2ae3b47fabb1f8995595ab474029da749a8be120" +checksum = "3a1f95c0d03a47f4ae1f7a64643a6bb97465d9b740f0fa8f90ea33915c99a9a1" dependencies = [ "js-sys", "wasm-bindgen", @@ -3920,15 +15125,139 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki-root-certs" +version = "0.26.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75c7f0ef91146ebfb530314f5f1d24528d7f0767efbfd31dce919275413e393e" +dependencies = [ + "webpki-root-certs 1.0.4", +] + +[[package]] +name = "webpki-root-certs" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee3e3b5f5e80bc89f30ce8d0343bf4e5f12341c51f3e26cbeecbc7c85443e85b" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "webpki-roots" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b130c0d2d49f8b6889abc456e795e82525204f27c42cf767cf0d7734e089b8" +checksum = "b2878ef029c47c6e8cf779119f20fcf52bde7ad42a731b2a304bc221df17571e" dependencies = [ "rustls-pki-types", ] +[[package]] +name = "wgpu" +version = "23.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80f70000db37c469ea9d67defdc13024ddf9a5f1b89cb2941b812ad7cde1735a" +dependencies = [ + "arrayvec", + "cfg_aliases 0.1.1", + "document-features", + "js-sys", + "log", + "naga", + "parking_lot", + "profiling", + "raw-window-handle", + "smallvec", + "static_assertions", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "wgpu-core", + "wgpu-hal", + "wgpu-types", +] + +[[package]] +name = "wgpu-core" +version = "23.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d63c3c478de8e7e01786479919c8769f62a22eec16788d8c2ac77ce2c132778a" +dependencies = [ + "arrayvec", + "bit-vec 0.8.0", + "bitflags 2.10.0", + "cfg_aliases 0.1.1", + "document-features", + "indexmap 2.12.1", + "log", + "naga", + "once_cell", + "parking_lot", + "profiling", + "raw-window-handle", + "rustc-hash 1.1.0", + "smallvec", + "thiserror 1.0.69", + "wgpu-hal", + "wgpu-types", +] + +[[package]] +name = "wgpu-hal" +version = "23.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89364b8a0b211adc7b16aeaf1bd5ad4a919c1154b44c9ce27838213ba05fd821" +dependencies = [ + "android_system_properties", + "arrayvec", + "ash", + "bit-set 0.8.0", + "bitflags 2.10.0", + "block", + "bytemuck", + "cfg_aliases 0.1.1", + "core-graphics-types", + "glow", + "glutin_wgl_sys", + "gpu-alloc", + "gpu-allocator", + "gpu-descriptor", + "js-sys", + "khronos-egl", + "libc", + "libloading", + "log", + "metal", + "naga", + "ndk-sys 0.5.0+25.2.9519653", + "objc", + "once_cell", + "parking_lot", + "profiling", + "range-alloc", + "raw-window-handle", + "renderdoc-sys", + "rustc-hash 1.1.0", + "smallvec", + "thiserror 1.0.69", + "wasm-bindgen", + "web-sys", + "wgpu-types", + "windows 0.58.0", + "windows-core 0.58.0", +] + +[[package]] +name = "wgpu-types" +version = "23.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "610f6ff27778148c31093f3b03abc4840f9636d58d597ca2f5977433acfe0068" +dependencies = [ + "bitflags 2.10.0", + "js-sys", + "web-sys", +] + [[package]] name = "winapi" version = "0.3.9" @@ -3945,23 +15274,85 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core 0.52.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +dependencies = [ + "windows-core 0.58.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +dependencies = [ + "windows-implement 0.58.0", + "windows-interface 0.58.0", + "windows-result 0.2.0", + "windows-strings 0.1.0", + "windows-targets 0.52.6", +] + [[package]] name = "windows-core" version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ - "windows-implement", - "windows-interface", + "windows-implement 0.60.2", + "windows-interface 0.59.3", "windows-link", - "windows-result", - "windows-strings", + "windows-result 0.4.1", + "windows-strings 0.5.1", +] + +[[package]] +name = "windows-implement" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", ] [[package]] @@ -3972,7 +15363,18 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", +] + +[[package]] +name = "windows-interface" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", ] [[package]] @@ -3983,7 +15385,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -3992,6 +15394,15 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-result" version = "0.4.1" @@ -4001,6 +15412,16 @@ dependencies = [ "windows-link", ] +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result 0.2.0", + "windows-targets 0.52.6", +] + [[package]] name = "windows-strings" version = "0.5.1" @@ -4010,6 +15431,24 @@ dependencies = [ "windows-link", ] +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + [[package]] name = "windows-sys" version = "0.52.0" @@ -4046,6 +15485,36 @@ dependencies = [ "windows-link", ] +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + [[package]] name = "windows-targets" version = "0.52.6" @@ -4079,6 +15548,18 @@ dependencies = [ "windows_x86_64_msvc 0.53.1", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" @@ -4091,6 +15572,18 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + [[package]] name = "windows_aarch64_msvc" version = "0.52.6" @@ -4103,6 +15596,18 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -4127,6 +15632,18 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + [[package]] name = "windows_i686_msvc" version = "0.52.6" @@ -4139,6 +15656,18 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + [[package]] name = "windows_x86_64_gnu" version = "0.52.6" @@ -4151,6 +15680,18 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" @@ -4163,6 +15704,18 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + [[package]] name = "windows_x86_64_msvc" version = "0.52.6" @@ -4175,6 +15728,50 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" +[[package]] +name = "winit" +version = "0.30.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c66d4b9ed69c4009f6321f762d6e61ad8a2389cd431b97cb1e146812e9e6c732" +dependencies = [ + "android-activity", + "atomic-waker", + "bitflags 2.10.0", + "block2 0.5.1", + "bytemuck", + "calloop", + "cfg_aliases 0.2.1", + "concurrent-queue", + "core-foundation 0.9.4", + "core-graphics", + "cursor-icon", + "dpi", + "js-sys", + "libc", + "ndk", + "objc2 0.5.2", + "objc2-app-kit", + "objc2-foundation", + "objc2-ui-kit", + "orbclient", + "percent-encoding", + "pin-project", + "raw-window-handle", + "redox_syscall 0.4.1", + "rustix 0.38.44", + "smol_str", + "tracing", + "unicode-segmentation", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "web-time", + "windows-sys 0.52.0", + "x11-dl", + "x11rb", + "xkbcommon-dl", +] + [[package]] name = "winnow" version = "0.7.13" @@ -4184,6 +15781,16 @@ dependencies = [ "memchr", ] +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "wit-bindgen" version = "0.46.0" @@ -4192,18 +15799,143 @@ checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" [[package]] name = "writeable" -version = "0.6.1" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" + +[[package]] +name = "wyz" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "x11-dl" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" +dependencies = [ + "libc", + "once_cell", + "pkg-config", +] + +[[package]] +name = "x11rb" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9993aa5be5a26815fe2c3eacfc1fde061fc1a1f094bf1ad2a18bf9c495dd7414" +dependencies = [ + "as-raw-xcb-connection", + "gethostname", + "libc", + "libloading", + "once_cell", + "rustix 1.1.2", + "x11rb-protocol", +] + +[[package]] +name = "x11rb-protocol" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" +checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd" + +[[package]] +name = "x509-parser" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4569f339c0c402346d4a75a9e39cf8dad310e287eef1ff56d4c68e5067f53460" +dependencies = [ + "asn1-rs", + "data-encoding", + "der-parser", + "lazy_static", + "nom", + "oid-registry", + "ring", + "rusticata-macros", + "thiserror 2.0.17", + "time", +] + +[[package]] +name = "xkbcommon-dl" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" +dependencies = [ + "bitflags 2.10.0", + "dlib", + "log", + "once_cell", + "xkeysym", +] + +[[package]] +name = "xkeysym" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" + +[[package]] +name = "xml-rs" +version = "0.8.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ae8337f8a065cfc972643663ea4279e04e7256de865aa66fe25cec5fb912d3f" + +[[package]] +name = "xmlparser" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4" [[package]] name = "xtask" version = "0.1.0" dependencies = [ "anyhow", + "ark-bn254 0.5.0", + "ark-groth16 0.5.0", + "ark-serialize 0.5.0", + "bincode", "clap", - "console", + "client-blockchain-sui", + "console 0.16.1", "directories", + "dotenvy", + "game-core", + "hex", + "serde", + "serde_json", + "shared-crypto", + "sp1-sdk", + "sp1-sui", + "sui-json-rpc-types", + "sui-keys", + "sui-sdk", + "sui-types", + "tokio", + "toml 0.8.23", + "zk", +] + +[[package]] +name = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map", ] [[package]] @@ -4218,18 +15950,26 @@ dependencies = [ ] [[package]] -name = "yansi" -version = "1.0.1" +name = "yasna" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" +dependencies = [ + "time", +] + +[[package]] +name = "yazi" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" +checksum = "c94451ac9513335b5e23d7a8a2b61a7102398b8cca5160829d313e84c9d98be1" [[package]] name = "yoke" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" dependencies = [ - "serde", "stable_deref_trait", "yoke-derive", "zerofrom", @@ -4237,34 +15977,40 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", - "synstructure", + "syn 2.0.110", + "synstructure 0.13.2", ] +[[package]] +name = "zeno" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd15f8e0dbb966fd9245e7498c7e9e5055d9e5c8b676b95bd67091cd11a1e697" + [[package]] name = "zerocopy" -version = "0.8.27" +version = "0.8.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" +checksum = "43fa6694ed34d6e57407afbccdeecfa268c470a7d2a5b0cf49ce9fcc345afb90" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.27" +version = "0.8.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" +checksum = "c640b22cd9817fae95be82f0d2f90b11f7605f6c319d16705c459b27ac2cbc26" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -4284,8 +16030,8 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", - "synstructure", + "syn 2.0.110", + "synstructure 0.13.2", ] [[package]] @@ -4305,14 +16051,14 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] name = "zerotrie" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" dependencies = [ "displaydoc", "yoke", @@ -4321,9 +16067,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.4" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" dependencies = [ "yoke", "zerofrom", @@ -4332,13 +16078,13 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -4348,8 +16094,68 @@ dependencies = [ "bincode", "game-core", "risc0-build", + "risc0-groth16", "risc0-zkvm", "serde", + "serde_json", + "sha2 0.10.9", + "sp1-build", + "sp1-sdk", "thiserror 2.0.17", "tracing", ] + +[[package]] +name = "zkhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4352d1081da6922701401cdd4cbf29a2723feb4cfabb5771f6fee8e9276da1c7" +dependencies = [ + "ark-ff 0.4.2", + "ark-std 0.4.0", + "bitvec 1.0.1", + "blake2", + "bls12_381", + "byteorder", + "cfg-if", + "group 0.12.1", + "group 0.13.0", + "halo2", + "hex", + "jubjub", + "lazy_static", + "pasta_curves 0.5.1", + "rand 0.8.5", + "serde", + "sha2 0.10.9", + "sha3", + "subtle", +] + +[[package]] +name = "zstd" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.16+zstd.1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/Cargo.toml b/Cargo.toml index 47998b1..8caaa24 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,9 +4,15 @@ members = [ "crates/game/content", "crates/runtime", "crates/zk", + + # Client binary and sub-crates + "crates/client", "crates/client/bootstrap", - "crates/client/core", - "crates/client/cli", + "crates/client/frontend/core", + "crates/client/frontend/cli", + "crates/client/frontend/bevy", + "crates/client/blockchain/sui", + "crates/xtask", "crates/behavior-tree", ] @@ -23,13 +29,18 @@ resolver = "2" # ---------------------------------------------------------------------------- # Internal Crates # ---------------------------------------------------------------------------- +# All internal crates use default-features = false for explicit feature control. +# Only binary crates (dungeon-client) should have default features. game-core = { path = "crates/game/core" } game-content = { path = "crates/game/content" } behavior-tree = { path = "crates/behavior-tree" } runtime = { path = "crates/runtime", default-features = false } zk = { path = "crates/zk", default-features = false } client-bootstrap = { path = "crates/client/bootstrap", default-features = false } -client-core = { path = "crates/client/core" } +client-frontend-core = { path = "crates/client/frontend/core", default-features = false } +client-frontend-cli = { path = "crates/client/frontend/cli", default-features = false } +client-frontend-bevy = { path = "crates/client/frontend/bevy", default-features = false } +client-blockchain-sui = { path = "crates/client/blockchain/sui", default-features = false } # ---------------------------------------------------------------------------- # Async Runtime @@ -45,7 +56,7 @@ serde = { version = "1.0", default-features = false, features = [ "derive", "alloc", ] } -serde_json = "1.0.145" +serde_json = "1.0" # NOTE: bincode 1.3 pinned for compatibility with risc0-zkvm 3.0 # Do not upgrade to bincode 2.0 until risc0-zkvm supports it bincode = "1.3" @@ -68,13 +79,26 @@ tracing-appender = "0.2" # ---------------------------------------------------------------------------- bounded-vector = { version = "0.3", default-features = false } arrayvec = { version = "0.7", default-features = false } -bitflags = { version = "2.9", default-features = false } +bitflags = { version = "2.10", default-features = false } +strum = { version = "0.26", default-features = false, features = ["derive"] } + +# ---------------------------------------------------------------------------- +# Cryptography (no_std compatible) +# ---------------------------------------------------------------------------- +sha2 = { version = "0.10", default-features = false } # ---------------------------------------------------------------------------- -# ZK Dependencies (only RISC0 is currently implemented) +# ZK Dependencies # ---------------------------------------------------------------------------- +# RISC0 zkVM risc0-zkvm = "3.0" risc0-build = "3.0" +risc0-groth16 = "3.0" + +# SP1 zkVM +sp1-sdk = { version = "5.2", features = ["network"] } +sp1-build = "5.2" +sp1-verifier = "5.2" # ---------------------------------------------------------------------------- # Terminal UI (client only) @@ -82,13 +106,21 @@ risc0-build = "3.0" ratatui = "0.29" crossterm = { version = "0.29", features = ["event-stream"] } +# ---------------------------------------------------------------------------- +# Game Engine (Bevy frontend) +# ---------------------------------------------------------------------------- +bevy = { version = "0.15", default-features = false } + # ---------------------------------------------------------------------------- # Utilities # ---------------------------------------------------------------------------- directories = "6.0" dotenvy = "0.15" +chrono = { version = "0.4", features = ["serde"] } +rand = "0.8" # ---------------------------------------------------------------------------- # Development & Testing # ---------------------------------------------------------------------------- tempfile = "3.23.0" +hex = "0.4" diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md new file mode 100644 index 0000000..216311c --- /dev/null +++ b/DEPLOYMENT.md @@ -0,0 +1,420 @@ +# Sui Blockchain Deployment Guide + +This guide covers the complete workflow for deploying Dungeon's Move contracts to Sui blockchain networks (local, testnet, or mainnet). + +## Prerequisites + +- Sui CLI installed (via suiup) +- Sui localnet running (for local deployment) +- Sufficient SUI tokens for gas (from faucet for testnet/local, purchased for mainnet) + +## Quick Start (Local Network) + +```bash +# 1. Start local network with faucet +just sui-localnet + +# 2. In a new terminal, generate address and fund it +cargo xtask sui keygen --alias local-dev +sui client faucet + +# 3. Deploy contracts +cd contracts/move +sui move build +sui client publish --gas-budget 10000000000 --with-unpublished-dependencies --json + +# 4. Save package ID and setup VK +# Copy the package ID from the output, then: +cargo xtask sui setup --network local +``` + +## Detailed Workflow + +### 1. Network Setup + +#### Local Network +```bash +# Start Sui local network with faucet (foreground) +just sui-localnet + +# Or manually: +sui start --force-regenesis --with-faucet + +# Network will be available at: +# - RPC: http://127.0.0.1:9000 +# - Faucet: http://0.0.0.0:9123 +``` + +#### Testnet +```bash +# Switch to testnet +sui client switch --env testnet + +# Verify connection +sui client envs +``` + +#### Mainnet +```bash +# Switch to mainnet +sui client switch --env mainnet + +# Verify connection +sui client envs +``` + +### 2. Address Management + +#### Generate New Address + +Using xtask (with alias support): +```bash +# Generate with alias +cargo xtask sui keygen --alias my-deployer + +# Generate with specific scheme +cargo xtask sui keygen --alias my-deployer --scheme ed25519 +``` + +Using Sui CLI directly: +```bash +# Generate ed25519 address (default) +sui client new-address ed25519 + +# Generate secp256k1 address +sui client new-address secp256k1 + +# Generate secp256r1 address +sui client new-address secp256r1 +``` + +#### Set Active Address + +By alias (xtask keygen only): +```bash +export SUI_ACTIVE_ALIAS=my-deployer +``` + +By address (Sui CLI): +```bash +sui client switch --address 0x... +``` + +#### Check Address Status +```bash +# View all addresses +sui client addresses + +# Check gas coins +sui client gas + +# Check all objects +sui client objects +``` + +### 3. Fund Address + +#### Local Network +```bash +# Request tokens from local faucet +sui client faucet + +# Verify balance +sui client gas +``` + +#### Testnet +```bash +# Request tokens from testnet faucet +sui client faucet + +# Or use the web faucet: +# https://faucet.testnet.sui.io/ +``` + +#### Mainnet +```bash +# Purchase SUI from an exchange +# Transfer to your address +``` + +### 4. Deploy Contracts + +```bash +# Navigate to contracts directory +cd contracts/move + +# Build the Move package +sui move build + +# Publish to blockchain +# Gas budget: 10 SUI = 10,000,000,000 MIST +sui client publish \ + --gas-budget 10000000000 \ + --with-unpublished-dependencies \ + --json + +# Example output: +# { +# "objectChanges": [ +# { +# "type": "published", +# "packageId": "0x1234...", +# ... +# } +# ], +# ... +# } +``` + +**Important Flags:** +- `--gas-budget`: Maximum gas to spend (in MIST, 1 SUI = 1,000,000,000 MIST) +- `--with-unpublished-dependencies`: Include unpublished dependencies (like Walrus) in the package +- `--json`: Output in JSON format for parsing + +**Save Package ID:** +Manually create `deployment/{network}.toml`: +```toml +network = "local" # or "testnet", "mainnet" +package_id = "0x1234..." # Copy from publish output +deployed_at = "2025-01-18T10:30:00Z" +``` + +### 5. Register Verifying Key + +After deployment, register the SP1 Groth16 verifying key on-chain: + +```bash +# Register VK for the deployed package +cargo xtask sui setup --network local + +# Or for testnet: +cargo xtask sui setup --network testnet + +# Skip VK registration if already done: +cargo xtask sui setup --network local --skip-vk +``` + +This command will: +1. Load deployment info from `deployment/{network}.toml` +2. Connect to the Sui network +3. Call `proof_verifier::create_verifying_key` with SP1 VK bytes +4. Save the VK object ID back to `deployment/{network}.toml` + +**Output:** +``` +🔧 Setting up Sui deployment for local... + +📝 Registering verifying key... + Using SP1 Groth16 VK v5.0.0 + VK size: 128 bytes + Connecting to: http://127.0.0.1:9000 + Using address: 0x... + Submitting transaction... + Transaction digest: ... + +✅ VK registered successfully! + VK Object ID: 0xabcd... + +📋 Deployment Summary: + Network: local + Package ID: 0x1234... + VK Object ID: 0xabcd... + +Next steps: + 1. Update .env with: + SUI_PACKAGE_ID=0x1234... + SUI_VK_OBJECT_ID=0xabcd... +``` + +### 6. Update Configuration + +Add the deployment info to your `.env` file: + +```bash +# Network configuration +SUI_NETWORK=local # or testnet, mainnet + +# Deployment info (from deployment/{network}.toml) +SUI_PACKAGE_ID=0x1234... +SUI_VK_OBJECT_ID=0xabcd... + +# Optional: Custom RPC URL +# SUI_RPC_URL=http://127.0.0.1:9000 + +# Optional: Gas budget (default: 0.1 SUI) +# SUI_GAS_BUDGET=100000000 +``` + +### 7. Verify Deployment + +```bash +# Check package info +sui client object + +# Check VK object +sui client object + +# Run client with Sui integration +just run-sui local +``` + +## Network-Specific Examples + +### Local Development +```bash +# Full workflow for local development +just sui-localnet # Terminal 1 + +# Terminal 2: +cargo xtask sui keygen --alias local-dev +export SUI_ACTIVE_ALIAS=local-dev +sui client faucet + +cd contracts/move +sui move build +sui client publish --gas-budget 10000000000 --with-unpublished-dependencies --json + +# Save package ID to deployment/local.toml +cargo xtask sui setup --network local + +# Update .env +echo "SUI_NETWORK=local" >> .env +echo "SUI_PACKAGE_ID=" >> .env +echo "SUI_VK_OBJECT_ID=" >> .env +``` + +### Testnet Deployment +```bash +# Switch to testnet +sui client switch --env testnet + +# Generate dedicated testnet address +cargo xtask sui keygen --alias testnet-deployer +export SUI_ACTIVE_ALIAS=testnet-deployer + +# Fund from faucet +sui client faucet + +# Deploy +cd contracts/move +sui move build +sui client publish --gas-budget 10000000000 --with-unpublished-dependencies --json + +# Save package ID to deployment/testnet.toml +cargo xtask sui setup --network testnet + +# Update .env for testnet +echo "SUI_NETWORK=testnet" >> .env +echo "SUI_PACKAGE_ID=" >> .env +echo "SUI_VK_OBJECT_ID=" >> .env +``` + +### Mainnet Deployment +```bash +# Switch to mainnet +sui client switch --env mainnet + +# Generate dedicated mainnet address (use hardware wallet in production!) +cargo xtask sui keygen --alias mainnet-deployer +export SUI_ACTIVE_ALIAS=mainnet-deployer + +# Fund address (purchase SUI from exchange) +# Verify balance: +sui client gas + +# Deploy with higher gas budget for mainnet +cd contracts/move +sui move build +sui client publish --gas-budget 20000000000 --with-unpublished-dependencies --json + +# Save package ID to deployment/mainnet.toml +cargo xtask sui setup --network mainnet + +# Update .env for mainnet +echo "SUI_NETWORK=mainnet" >> .env +echo "SUI_PACKAGE_ID=" >> .env +echo "SUI_VK_OBJECT_ID=" >> .env +``` + +## Troubleshooting + +### "Package dependency does not specify a published address" +**Solution:** Use `--with-unpublished-dependencies` flag when publishing. + +### "Connection refused" to faucet +**Solution:** Ensure localnet was started with `--with-faucet` flag: +```bash +sui start --force-regenesis --with-faucet +``` + +### "Insufficient gas" +**Solution:** Increase `--gas-budget` or fund address with more SUI: +```bash +sui client faucet # For local/testnet +``` + +### "No addresses in keystore" +**Solution:** Generate an address first: +```bash +cargo xtask sui keygen --alias my-address +# or +sui client new-address ed25519 +``` + +### "Address with alias not found" +**Solution:** List available addresses and use correct alias: +```bash +sui client addresses +export SUI_ACTIVE_ALIAS= +``` + +## Reference + +### Gas Budget Guidelines +- **Local/Testnet:** 0.1-1 SUI (100,000,000 - 1,000,000,000 MIST) +- **Mainnet:** 1-10 SUI (1,000,000,000 - 10,000,000,000 MIST) +- Conversion: 1 SUI = 1,000,000,000 MIST + +### Network URLs +- **Local:** `http://127.0.0.1:9000` +- **Testnet:** `https://fullnode.testnet.sui.io:443` +- **Mainnet:** `https://fullnode.mainnet.sui.io:443` + +### Faucet URLs +- **Local:** `http://0.0.0.0:9123` +- **Testnet (CLI):** `sui client faucet` +- **Testnet (Web):** https://faucet.testnet.sui.io/ + +### Useful Commands +```bash +# View current environment +sui client envs + +# View active address +sui client active-address + +# View all addresses with aliases +sui client addresses + +# View gas coins +sui client gas + +# View all owned objects +sui client objects + +# View specific object +sui client object + +# View transaction +sui client tx-block +``` + +## Next Steps + +After successful deployment: +1. Update `.env` with deployment info +2. Test contract interaction: `just run-sui local` +3. Create a game session on-chain +4. Submit proofs to verify functionality +5. For production: Consider using a hardware wallet for the deployer key diff --git a/README.md b/README.md index da8cc39..aa37762 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,14 @@ # Dungeon -> **⚠️ Early-stage prototype:** expect rapid iteration, missing features, and breaking changes. We’re sharing the core architecture early so contributors can help shape the design. +> **⚠️ Early-stage prototype:** expect rapid iteration, missing features, and breaking changes. We're sharing the core architecture early so contributors can help shape the design. Dungeon is a **verifiable roguelike RPG** — a deterministic world where every turn can be proven valid, yet not all truths are visible. -Built on zero-knowledge proofs (ZKPs), Dungeon ensures that every action, roll, and AI move followed the rules **without revealing** hidden information. -The result is a game that’s both **honest and mysterious** — fair because it’s provable, alive because it’s systemic. +Built on zero-knowledge proofs (ZKPs), Dungeon ensures that every action, roll, and AI move followed the rules **without revealing** hidden information. +The result is a game that's both **honest and mysterious** — fair because it's provable, alive because it's systemic. -At its core, Dungeon explores how **games can become transparent systems of truth** rather than opaque entertainment products. -Each world is procedural, deterministic, and shaped by interacting systems rather than scripts. +At its core, Dungeon explores how **games can become transparent systems of truth** rather than opaque entertainment products. +Each world is procedural, deterministic, and shaped by interacting systems rather than scripts. Your choices — lighting a torch, sparing an enemy, sealing a door — ripple through the rule system to form emergent stories that feel inevitable, not authored. > *Fairness without authority. Secrecy without deceit.* @@ -20,29 +20,36 @@ Learn more about the design vision and philosophy in [**philosophy.md**](./docs/ ``` crates/ ├── client/ -│ ├── core/ # Shared UX glue: config, messages, view models, oracle factories -│ └── frontend/ -│ ├── core/ # Frontend abstraction layer: FrontendApp trait, message routing -│ └── cli/ # Async terminal application with cursor system and examine UI +│ ├── bootstrap/ # Runtime initialization and configuration +│ ├── frontend/ +│ │ ├── core/ # Frontend abstraction: events, messages, view models +│ │ └── cli/ # Terminal UI with examine mode and targeting system +│ └── blockchain/ +│ └── sui/ # Sui blockchain client implementation ├── game/ │ ├── core/ # Pure deterministic state machine (actions, engine, validation) │ └── content/ # Static content and fixtures (maps, items, NPCs, loot tables) -├── runtime/ # Public API (RuntimeHandle), orchestrator, workers, oracles, repositories -└── zk/ # Proving utilities (planned for prover worker and off-chain services) +├── runtime/ # Orchestration layer: workers, AI, persistence, oracles +├── zk/ # Multi-backend ZK proving system (RISC0, SP1, stub) +└── xtask/ # Development tools (cargo xtask pattern) +contracts/move/ # Sui Move smart contracts (game sessions, proof verification) docs/ # Architecture, research notes, design decisions ``` ## Prerequisites -- Rust toolchain (1.85+ recommended). Install via [rustup](https://rustup.rs/) if you have not already. -- `cargo` (bundled with the Rust toolchain). -- [`just`](https://github.com/casey/just) command runner (recommended): `cargo install just` +- **Rust toolchain** (1.85+ recommended): Install via [rustup](https://rustup.rs/) +- **Just command runner** (recommended): `cargo install just` +- **Sui CLI** (for blockchain deployment): Install via [suiup](https://docs.sui.io/guides/developer/getting-started/sui-install) +- **SP1 toolchain** (for SP1 backend): Install via [sp1up](https://docs.succinct.xyz/getting-started/install.html) Some crates use async runtimes (`tokio`) and expect a POSIX-like environment. All commands below assume you are in the repository root. ## Quick Start +### Local Gameplay (No Blockchain) + **Recommended:** Use `just` for easier multi-backend development: ```bash @@ -50,76 +57,405 @@ Some crates use async runtimes (`tokio`) and expect a POSIX-like environment. Al cargo install just # Fast development with stub backend (no real proofs) -just build stub -just run stub -just test stub +just build stub cli +just run stub cli # Fast mode (no proof generation, no persistence) -just run-fast stub +just run-fast stub cli + +# Production build with SP1 Groth16 proofs +just build-release sp1 cli +just run-release sp1 cli # Set default backend via environment export ZK_BACKEND=stub -just build # uses stub automatically -just run +just build cli # uses stub automatically +just run cli # See all available commands just --list just help ``` -### Available ZK Backends +### With Sui Blockchain Integration + +```bash +# Build with Sui blockchain support +just build-release sp1 cli sui + +# Run with Sui testnet (requires .env configuration) +just run-release sp1 cli sui +``` + +See [**DEPLOYMENT.md**](./DEPLOYMENT.md) for comprehensive blockchain deployment instructions. + +## Available ZK Backends + +Dungeon supports multiple ZK proof backends through feature flags: + +| Backend | Status | Proof Type | Size | Speed | Use Case | +|---------|--------|------------|------|-------|----------| +| **stub** | ✅ Implemented | None (instant) | N/A | Instant | Development, testing | +| **risc0** | ✅ Implemented | Groth16 SNARK | ~200 bytes | Slow | Production (Linux x86_64 only) | +| **sp1** | ✅ Implemented | Groth16/PLONK SNARK | ~260 bytes | Medium | Production (all platforms) | +| **arkworks** | 📅 Planned | Custom circuits | TBD | TBD | Future optimization | + +**Recommended for development:** `stub` (instant, no setup) +**Recommended for production:** `sp1` (cross-platform, mature tooling) + +### Backend Configuration + +Set the default backend via environment variable: + +```bash +export ZK_BACKEND=stub # or risc0, sp1, arkworks +just build # automatically uses $ZK_BACKEND +just run +``` + +Or specify explicitly: + +```bash +just build-release sp1 cli # Build with SP1 backend and CLI frontend +just run risc0 cli sui # Run with RISC0 backend, CLI, and Sui integration +``` + +### Feature Flags + +Features can be combined flexibly: + +```bash +# Backend features (mutually exclusive) +stub # Stub prover (testing only) +risc0 # RISC0 zkVM backend +sp1 # SP1 zkVM backend +arkworks # Arkworks circuits (planned) + +# Frontend features (can combine) +cli # Terminal UI frontend + +# Blockchain features (can combine) +sui # Sui blockchain integration + +# Examples +just build stub cli # Local play, no proofs +just build-release sp1 cli # Local play with SP1 proofs +just build-release sp1 cli sui # Full stack: SP1 + CLI + Sui +just run-fast stub cli # Fast mode: no proofs, no persistence +``` + +## Common Just Commands + +### Building and Running + +| Command | Description | +|---------|-------------| +| `just build ` | Build workspace with specified features | +| `just run ` | Run CLI client with specified features | +| `just run-fast ` | Run in fast mode (no proofs, no persistence) | +| `just run-release ` | Run optimized release build | +| `just build-release ` | Build optimized release binary | + +### Development Workflow + +| Command | Description | +|---------|-------------| +| `just dev` | Fast dev loop: format + lint + test (stub backend) | +| `just fmt` | Format all code with rustfmt | +| `just lint ` | Run clippy lints with specified features | +| `just test ` | Run all tests with specified features | +| `just check ` | Run format + lint + tests together | +| `just pre-commit` | Pre-commit checks (recommended before committing) | + +### Testing and Validation + +| Command | Description | +|---------|-------------| +| `just test ` | Run all tests | +| `just test-lib ` | Run library tests only | +| `just test-integration ` | Run integration tests only | +| `just check-all` | Verify all backends compile (CI use) | +| `just ci` | Full CI simulation | + +### Data and Logs + +| Command | Description | +|---------|-------------| +| `just tail-logs [session]` | Monitor client logs in real-time | +| `just sessions` | List all available game sessions | +| `just read-state ` | Inspect saved game state at nonce | +| `just read-actions [nonce]` | Inspect action log for session | +| `just clean-data` | Clean save data and logs (with confirmation) | +| `just clean-logs` | Clean only logs (faster) | + +### Documentation and Info + +| Command | Description | +|---------|-------------| +| `just help` | Show detailed help with examples | +| `just info` | Show current backend configuration | +| `just doc ` | Generate and open documentation | +| `just --list` | List all available commands | + +## Environment Variables + +### General Configuration + +```bash +# ZK Backend selection +ZK_BACKEND=stub # Default backend for just commands (stub, risc0, sp1) + +# Runtime behavior +ENABLE_ZK_PROVING=false # Disable proof generation (fast mode) +ENABLE_PERSISTENCE=false # Disable state/action persistence (fast mode) +RUST_LOG=info # Logging level (info, warn, debug) +``` + +### RISC0 Specific -- `risc0` - RISC0 zkVM (production, real proofs, slow) -- `stub` - Stub prover (instant, no proofs, testing only) -- `sp1` - SP1 zkVM (not implemented yet) -- `arkworks` - Arkworks circuits (not implemented yet) +```bash +RISC0_SKIP_BUILD=1 # Skip guest builds during cargo build +RISC0_DEV_MODE=1 # Fast dev proofs (when using risc0 backend) +``` -### Common Just Commands +### SP1 Specific -| Task | Command | -|------|---------| -| Build with backend | `just build [backend]` | -| Run CLI client | `just run [backend]` | -| Run in fast mode | `just run-fast [backend]` (no proofs, no persistence) | -| Run all tests | `just test [backend]` | -| Lint code | `just lint [backend]` | -| Format code | `just fmt` | -| Pre-commit checks | `just pre-commit` | -| Verify all backends | `just check-all` | -| Fast dev loop | `just dev` (format + lint + test stub) | -| Monitor logs | `just tail-logs [session]` | -| Clean data | `just clean-data` | +```bash +SP1_PROVER=network # SP1 prover mode (cpu, network, cuda, mock) +SP1_PROOF_MODE=groth16 # SP1 proof type (compressed, groth16, plonk) +NETWORK_PRIVATE_KEY= # Private key for SP1 Prover Network +``` + +### Sui Blockchain + +```bash +SUI_NETWORK=testnet # Sui network (local, testnet, mainnet) +SUI_PACKAGE_ID=0x... # Deployed game contract package ID +SUI_VK_OBJECT_ID=0x... # Verifying key object ID +SUI_RPC_URL= # Custom RPC endpoint (optional) +SUI_GAS_BUDGET=100000000 # Gas budget in MIST (default: 0.1 SUI) +``` -### Direct Cargo Commands (without Just) +See [`.env.example`](.env.example) for a complete configuration template. -If you prefer not to use `just`, you can use cargo directly: +## Sui Blockchain Integration + +Dungeon integrates with Sui blockchain for: + +- **On-chain game sessions**: Create and manage game sessions as Sui objects +- **Proof verification**: Submit ZK proofs for validation (currently disabled - see Known Issues) +- **Action log storage**: Store action sequences in Walrus decentralized storage +- **Challenge period**: Time-delayed finalization for dispute resolution + +### Deployment Workflow + +1. **Deploy Move contracts to Sui testnet**: + ```bash + sui client switch --env testnet + sui client faucet + sui client publish --path contracts/move --gas-budget 500000000 --with-unpublished-dependencies + ``` + +2. **Configure environment**: + ```bash + # Copy deployment info to .env + SUI_NETWORK=testnet + SUI_PACKAGE_ID= + ``` + +3. **Run client with Sui integration**: + ```bash + just run sp1 cli sui + ``` + +See [**DEPLOYMENT.md**](./DEPLOYMENT.md) for comprehensive deployment instructions including: +- Network setup (local, testnet, mainnet) +- Address management and funding +- Contract deployment and upgrades +- Troubleshooting common issues + +### Walrus Decentralized Storage + +Action logs are stored in [Walrus](https://walrus.xyz/), a decentralized blob storage protocol built on Sui: + +- **Cryptographic integrity**: Blob IDs serve as content-addressed action roots +- **Availability guarantees**: Redundant storage across multiple storage nodes +- **Challenge period**: Action logs retained on-chain for dispute resolution +- **Gas efficiency**: Large action sequences stored off-chain, only commitments on-chain + +## Known Issues + +### ZK Proof Verification (Temporary) + +**Status**: ZK proof generation works perfectly, but on-chain verification is temporarily disabled. + +**Reason**: SP1 5.2 Groth16 verifying key format is incompatible with Sui's `groth16` Move module. This is a known serialization format issue between SP1 SDK versions. + +**What Works**: +- ✅ Proof generation (SP1 Groth16 proofs are generated successfully) +- ✅ All proof data is correctly structured (journal, public inputs, proof points) +- ✅ Blockchain transaction submission +- ✅ Action log storage in Walrus + +**What's Disabled**: +- ❌ On-chain ZK proof verification (commented out in `game_session.move`) + +**Post-Hackathon Plan**: +- Investigate exact VK format requirements for Sui's groth16 module +- Either downgrade SP1 to 5.0.0 or await sp1-sui compatibility update +- Re-enable verification once VK compatibility is resolved + +See [`contracts/move/sources/game_session.move:227-251`](contracts/move/sources/game_session.move#L227-L251) for detailed technical comments. + +## Architecture + +```mermaid +flowchart TB + %% --- Node Styling Definitions --- + classDef frontend fill:#bbdefb,stroke:#1976d2,stroke-width:2px,color:#0d47a1; + classDef client fill:#c5cae9,stroke:#303f9f,stroke-width:2px,color:#1a237e; + classDef runtime fill:#b2dfdb,stroke:#00796b,stroke-width:2px,color:#004d40; + classDef core fill:#ffccbc,stroke:#d84315,stroke-width:2px,color:#bf360c; + classDef zk fill:#e1bee7,stroke:#7b1fa2,stroke-width:2px,color:#4a148c; + classDef chain fill:#cfd8dc,stroke:#455a64,stroke-width:2px,color:#263238; + classDef walrus fill:#ffe0b2,stroke:#f57c00,stroke-width:2px,color:#e65100; + + %% --- Subgraphs & Nodes --- + subgraph Frontends ["🖥️ Presentation Layer"] + direction TB + cli_client["📟 Terminal UI
(client/frontend/cli)"]:::frontend + future_ui["🌐 Future Frontends
(Bevy, WebAssembly)"]:::frontend + end + + subgraph Client ["🔌 Client Layer"] + direction TB + orchestrator["🎬 Client Orchestrator"]:::client + blockchain_client["🔗 Blockchain Client
(Sui Adapter)"]:::client + end + + subgraph Runtime ["⚙️ Runtime Layer"] + direction TB + api_mod["📡 api/
RuntimeHandle · GameEvent"]:::runtime + runtime_orch["🧠 Runtime Orchestrator"]:::runtime + workers_mod["👷 workers/
Simulation · Prover · Persistence"]:::runtime + oracle_mod["🔮 oracle/
MapOracle · ItemOracle"]:::runtime + repo_mod["💾 repository/
ActionBatch · StateRepo"]:::runtime + end + + subgraph Game ["🦀 Game Logic (Shared)"] + direction TB + game_core["🧩 game-core
(Engine, State, Actions)"]:::core + game_content["📦 game-content
(Static Assets)"]:::core + end + + subgraph ZK ["🔐 Zero-Knowledge"] + direction TB + prover_backend["🛡️ Proving Backends
(RISC0, SP1, Stub)"]:::zk + end + + subgraph Infrastructure ["☁️ On-Chain & Storage"] + direction TB + move_contract["💧 Game Session
(Sui Move)"]:::chain + walrus["🦭 Walrus Storage
(Action Logs)"]:::walrus + end + + %% --- Connections --- + cli_client -->|"implements"| orchestrator + + orchestrator -->|"initializes"| runtime_orch + orchestrator -->|"uses"| blockchain_client + + blockchain_client -.->|"submits proofs"| move_contract + blockchain_client -.->|"uploads logs"| walrus + + runtime_orch -->|"exposes"| api_mod + runtime_orch -->|"manages"| workers_mod + + workers_mod -->|"executes"| game_core + workers_mod -->|"generates proofs"| prover_backend + workers_mod -->|"persists"| repo_mod + workers_mod -->|"injects Oracle"| game_core + + oracle_mod -->|"wraps"| game_content + oracle_mod -.->|"implements traits"| game_core + + prover_backend -->|"proves"| game_core + + %% --- Background Styling (Soft Pastel Colors) --- + style Frontends fill:#f0f8ff,stroke:#90caf9,stroke-width:1px,stroke-dasharray: 5 5 + style Client fill:#f3f4fa,stroke:#9fa8da,stroke-width:1px,stroke-dasharray: 5 5 + style Runtime fill:#e8f5e9,stroke:#80cbc4,stroke-width:1px,stroke-dasharray: 5 5 + style Game fill:#fffbe6,stroke:#ffab91,stroke-width:1px,stroke-dasharray: 5 5 + style ZK fill:#f3e5f5,stroke:#ce93d8,stroke-width:1px,stroke-dasharray: 5 5 + style Infrastructure fill:#f5f5f5,stroke:#b0bec5,stroke-width:1px,stroke-dasharray: 5 5 +``` + +### Three-Layer Design + +1. **game-core**: Pure deterministic state machine + - 3-phase action pipeline (pre_validate → apply → post_validate) + - 5-layer stat system with unified bonus calculations + - Oracle pattern for static content + - Zero dependencies on I/O, randomness, or crypto + +2. **runtime**: Orchestration and side effects + - Worker system (SimulationWorker, ProverWorker, PersistenceWorker) + - Topic-based event bus for reactive updates + - Utility-based AI (Intent → Tactic → Action) + - Repository layer for state/checkpoint/log persistence + +3. **client**: Multi-frontend architecture + - Terminal UI with examine mode and tactical targeting + - Sui blockchain client for proof submission + - Shared UX primitives across frontends + +See [`docs/architecture.md`](docs/architecture.md) for detailed design documentation. + +## Development Tools (xtask) + +The `xtask` crate provides development utilities following the [cargo xtask pattern](https://github.com/matklad/cargo-xtask): ```bash -# Stub backend (fast development) -cargo build --workspace --no-default-features --features stub -cargo run -p client-cli --no-default-features --features stub -cargo test --workspace --no-default-features --features stub - -# RISC0 backend (default) -cargo build --workspace -RISC0_SKIP_BUILD=1 cargo build --workspace # skip guest builds - -# Format and lint -cargo fmt --all -cargo clippy --workspace --all-targets +# List available tasks +cargo xtask --help + +# Tail logs for a session +cargo xtask tail-logs --session + +# Clean save data and logs +cargo xtask clean-data --all + +# Extract SP1 VK from proof (for debugging) +cargo xtask extract-vk --proof proof.bin --output vk.bin + +# Inspect proof structure +cargo xtask inspect-proof --proof proof.bin + +# Sui deployment helpers +cargo xtask sui keygen --alias my-key +cargo xtask sui setup --network testnet ``` ## Contributing We welcome contributions! -Please read the full [Contributing Guidelines](.github/CONTRIBUTING.md) before opening a Pull Request. ---- +**Before submitting a PR**: +1. Run `just pre-commit` to ensure all checks pass +2. Read the full [Contributing Guidelines](.github/CONTRIBUTING.md) +3. Check [`TODOs.md`](TODOs.md) for prioritized tasks + +**Development workflow**: +```bash +just dev # Format, lint, test (fast iteration) +just check-all # Verify all backends compile +just pre-commit # Final checks before committing +``` ## Additional Resources -- [`docs/architecture.md`](docs/architecture.md) – High-level diagrams and subsystem overviews -- [`docs/status.md`](docs/status.md) – Current implementation status and roadmap (updated frequently) -- [`docs/research.md`](docs/research.md) – Exploratory notes and design investigations -- [`.github/CONTRIBUTING.md`](.github/CONTRIBUTING.md) – Contributing guidelines and code standards -- [`CLAUDE.md`](CLAUDE.md), [`AGENTS.md`](AGENTS.md) – Development guidance for AI-assisted coding +- [**CLAUDE.md**](CLAUDE.md) – Comprehensive project guide for AI-assisted development +- [**DEPLOYMENT.md**](DEPLOYMENT.md) – Sui blockchain deployment instructions +- [**docs/architecture.md**](docs/architecture.md) – High-level system design and diagrams +- [**docs/philosophy.md**](docs/philosophy.md) – Design vision and motivations +- [**.github/CONTRIBUTING.md**](.github/CONTRIBUTING.md) – Contributing guidelines and code standards diff --git a/assets/generate_sprites.py b/assets/generate_sprites.py new file mode 100644 index 0000000..3d5f7ca --- /dev/null +++ b/assets/generate_sprites.py @@ -0,0 +1,384 @@ +#!/usr/bin/env python3 +"""Generate 32x32 pixel art sprites for the dungeon game.""" + +from PIL import Image, ImageDraw + +SIZE = 32 + + +def create_sprite(draw_func, filename): + """Create a 32x32 sprite with the given drawing function.""" + img = Image.new("RGBA", (SIZE, SIZE), (0, 0, 0, 0)) + draw = ImageDraw.Draw(img) + draw_func(draw) + img.save(f"sprites/{filename}") + print(f"Created sprites/{filename}") + + +# ============================================================================ +# Terrain Tiles +# ============================================================================ + + +def draw_floor(draw): + """Stone floor tile with subtle texture.""" + # Base color + draw.rectangle([0, 0, SIZE - 1, SIZE - 1], fill=(70, 70, 80, 255)) + # Stone texture lines + for i in range(0, SIZE, 8): + draw.line([(i, 0), (i, SIZE - 1)], fill=(60, 60, 70, 255), width=1) + draw.line([(0, i), (SIZE - 1, i)], fill=(60, 60, 70, 255), width=1) + # Add some dots for texture + for x in range(4, SIZE, 8): + for y in range(4, SIZE, 8): + draw.point((x, y), fill=(80, 80, 90, 255)) + + +def draw_wall(draw): + """Stone wall with brick pattern.""" + # Base color + draw.rectangle([0, 0, SIZE - 1, SIZE - 1], fill=(100, 80, 60, 255)) + # Brick pattern + brick_h = 8 + for row in range(4): + y = row * brick_h + offset = (row % 2) * (SIZE // 2) + for col in range(-1, 3): + x = col * SIZE // 2 + offset + # Brick outline + draw.rectangle( + [x + 1, y + 1, x + SIZE // 2 - 2, y + brick_h - 2], + fill=(110, 90, 70, 255), + outline=(80, 60, 45, 255), + ) + # Highlight top + draw.line([(0, 0), (SIZE - 1, 0)], fill=(130, 110, 90, 255), width=1) + + +def draw_void(draw): + """Dark void/abyss.""" + draw.rectangle([0, 0, SIZE - 1, SIZE - 1], fill=(15, 15, 25, 255)) + # Add subtle stars/specks + import random + + random.seed(42) # Deterministic + for _ in range(8): + x, y = random.randint(0, SIZE - 1), random.randint(0, SIZE - 1) + draw.point((x, y), fill=(40, 40, 60, 255)) + + +def draw_water(draw): + """Animated water tile (static frame).""" + # Base water color + draw.rectangle([0, 0, SIZE - 1, SIZE - 1], fill=(30, 80, 150, 255)) + # Wave pattern + for y in range(0, SIZE, 6): + for x in range(SIZE): + offset = (x // 4) % 2 + if (y + offset * 3) % 6 < 3: + draw.point((x, y), fill=(50, 100, 180, 255)) + draw.point((x, y + 1), fill=(40, 90, 160, 255)) + # Highlights + draw.line([(4, 8), (12, 8)], fill=(80, 130, 200, 255), width=1) + draw.line([(18, 20), (28, 20)], fill=(80, 130, 200, 255), width=1) + + +def draw_custom(draw): + """Custom terrain (purple mystery tile).""" + draw.rectangle([0, 0, SIZE - 1, SIZE - 1], fill=(100, 40, 120, 255)) + # Diamond pattern + center = SIZE // 2 + draw.polygon( + [(center, 4), (SIZE - 4, center), (center, SIZE - 4), (4, center)], + fill=(130, 60, 150, 255), + outline=(80, 30, 100, 255), + ) + # Center dot + draw.ellipse([center - 3, center - 3, center + 3, center + 3], fill=(180, 100, 200, 255)) + + +# ============================================================================ +# Actors +# ============================================================================ + + +def draw_player(draw): + """Player character - heroic figure.""" + # Body (green tunic) + draw.rectangle([10, 12, 21, 24], fill=(40, 160, 60, 255)) + # Head + draw.ellipse([11, 4, 20, 13], fill=(220, 180, 140, 255)) + # Eyes + draw.point((14, 8), fill=(40, 40, 40, 255)) + draw.point((17, 8), fill=(40, 40, 40, 255)) + # Hair + draw.arc([11, 2, 20, 10], 0, 180, fill=(100, 70, 40, 255), width=2) + # Arms + draw.rectangle([6, 14, 10, 20], fill=(220, 180, 140, 255)) + draw.rectangle([21, 14, 25, 20], fill=(220, 180, 140, 255)) + # Legs + draw.rectangle([11, 24, 15, 30], fill=(60, 50, 40, 255)) + draw.rectangle([16, 24, 20, 30], fill=(60, 50, 40, 255)) + # Sword (right hand) + draw.rectangle([24, 8, 26, 20], fill=(180, 180, 190, 255)) + draw.rectangle([23, 18, 27, 20], fill=(140, 100, 60, 255)) + + +def draw_enemy_goblin(draw): + """Goblin enemy - small green creature.""" + # Body (greenish) + draw.ellipse([8, 12, 23, 26], fill=(80, 130, 70, 255)) + # Head + draw.ellipse([10, 4, 21, 15], fill=(90, 140, 80, 255)) + # Big ears + draw.polygon([(8, 8), (4, 2), (10, 10)], fill=(90, 140, 80, 255)) + draw.polygon([(23, 8), (27, 2), (21, 10)], fill=(90, 140, 80, 255)) + # Eyes (angry red) + draw.ellipse([12, 7, 15, 11], fill=(200, 50, 50, 255)) + draw.ellipse([16, 7, 19, 11], fill=(200, 50, 50, 255)) + draw.point((13, 8), fill=(255, 255, 255, 255)) + draw.point((17, 8), fill=(255, 255, 255, 255)) + # Mouth + draw.arc([13, 10, 18, 14], 0, 180, fill=(40, 40, 40, 255), width=1) + # Legs + draw.rectangle([10, 25, 14, 30], fill=(80, 130, 70, 255)) + draw.rectangle([17, 25, 21, 30], fill=(80, 130, 70, 255)) + + +def draw_enemy_skeleton(draw): + """Skeleton enemy - undead warrior.""" + # Skull + draw.ellipse([10, 3, 21, 14], fill=(240, 240, 230, 255)) + # Eye sockets + draw.ellipse([12, 6, 15, 10], fill=(20, 20, 20, 255)) + draw.ellipse([16, 6, 19, 10], fill=(20, 20, 20, 255)) + # Nose hole + draw.polygon([(15, 10), (16, 10), (15.5, 12)], fill=(20, 20, 20, 255)) + # Teeth + draw.rectangle([12, 12, 19, 14], fill=(240, 240, 230, 255)) + draw.line([(14, 12), (14, 14)], fill=(20, 20, 20, 255), width=1) + draw.line([(17, 12), (17, 14)], fill=(20, 20, 20, 255), width=1) + # Ribcage + draw.rectangle([11, 15, 20, 24], fill=(230, 230, 220, 255)) + for y in range(16, 24, 2): + draw.line([(12, y), (19, y)], fill=(200, 200, 190, 255), width=1) + # Arms (bones) + draw.line([(8, 16), (8, 22)], fill=(240, 240, 230, 255), width=2) + draw.line([(23, 16), (23, 22)], fill=(240, 240, 230, 255), width=2) + # Legs (bones) + draw.line([(13, 24), (13, 30)], fill=(240, 240, 230, 255), width=2) + draw.line([(18, 24), (18, 30)], fill=(240, 240, 230, 255), width=2) + + +def draw_enemy_slime(draw): + """Slime enemy - blob creature.""" + # Main body (jelly) + draw.ellipse([4, 10, 27, 28], fill=(100, 180, 100, 180)) + # Highlight + draw.ellipse([6, 12, 14, 18], fill=(140, 220, 140, 150)) + # Eyes + draw.ellipse([10, 16, 14, 20], fill=(255, 255, 255, 255)) + draw.ellipse([17, 16, 21, 20], fill=(255, 255, 255, 255)) + draw.ellipse([11, 17, 13, 19], fill=(20, 20, 20, 255)) + draw.ellipse([18, 17, 20, 19], fill=(20, 20, 20, 255)) + # Happy mouth + draw.arc([12, 20, 19, 25], 0, 180, fill=(60, 120, 60, 255), width=2) + + +# ============================================================================ +# Props +# ============================================================================ + + +def draw_door_closed(draw): + """Closed wooden door.""" + # Door frame + draw.rectangle([4, 2, 27, 29], fill=(80, 60, 40, 255)) + # Door panels + draw.rectangle([6, 4, 25, 27], fill=(120, 90, 60, 255)) + # Planks + draw.line([(6, 10), (25, 10)], fill=(100, 75, 50, 255), width=1) + draw.line([(6, 18), (25, 18)], fill=(100, 75, 50, 255), width=1) + # Handle + draw.ellipse([20, 14, 24, 18], fill=(200, 180, 100, 255)) + + +def draw_door_open(draw): + """Open door (passable).""" + # Door frame + draw.rectangle([4, 2, 27, 29], fill=(80, 60, 40, 255)) + # Opening (dark) + draw.rectangle([6, 4, 25, 27], fill=(30, 30, 35, 255)) + # Door edge (ajar) + draw.polygon([(6, 4), (10, 4), (8, 27), (6, 27)], fill=(120, 90, 60, 255)) + + +def draw_switch_off(draw): + """Lever/switch in off position.""" + # Base plate + draw.rectangle([8, 20, 23, 28], fill=(100, 100, 110, 255)) + # Lever base + draw.ellipse([12, 18, 19, 25], fill=(80, 80, 90, 255)) + # Lever arm (down position) + draw.line([(15, 21), (10, 10)], fill=(140, 140, 150, 255), width=3) + draw.ellipse([8, 8, 12, 12], fill=(180, 80, 80, 255)) + + +def draw_switch_on(draw): + """Lever/switch in on position.""" + # Base plate + draw.rectangle([8, 20, 23, 28], fill=(100, 100, 110, 255)) + # Lever base + draw.ellipse([12, 18, 19, 25], fill=(80, 80, 90, 255)) + # Lever arm (up position) + draw.line([(15, 21), (20, 10)], fill=(140, 140, 150, 255), width=3) + draw.ellipse([18, 8, 22, 12], fill=(80, 180, 80, 255)) + + +def draw_hazard(draw): + """Hazard/trap tile (spikes).""" + # Base + draw.rectangle([0, 24, SIZE - 1, SIZE - 1], fill=(80, 70, 60, 255)) + # Spikes + for x in range(4, SIZE - 2, 6): + draw.polygon([(x, 24), (x + 3, 6), (x + 6, 24)], fill=(160, 160, 170, 255)) + # Spike highlight + draw.line([(x + 3, 6), (x + 3, 24)], fill=(200, 200, 210, 255), width=1) + + +# ============================================================================ +# Items +# ============================================================================ + + +def draw_item_potion_health(draw): + """Red health potion.""" + # Bottle body + draw.ellipse([8, 12, 23, 28], fill=(180, 40, 40, 255)) + # Bottle neck + draw.rectangle([12, 6, 19, 14], fill=(180, 40, 40, 255)) + # Cork + draw.rectangle([13, 4, 18, 8], fill=(140, 100, 60, 255)) + # Highlight + draw.ellipse([10, 14, 14, 20], fill=(220, 80, 80, 255)) + # Label + draw.rectangle([10, 20, 21, 24], fill=(240, 240, 230, 255)) + draw.text((12, 19), "+", fill=(180, 40, 40, 255)) + + +def draw_item_potion_mana(draw): + """Blue mana potion.""" + # Bottle body + draw.ellipse([8, 12, 23, 28], fill=(40, 80, 180, 255)) + # Bottle neck + draw.rectangle([12, 6, 19, 14], fill=(40, 80, 180, 255)) + # Cork + draw.rectangle([13, 4, 18, 8], fill=(140, 100, 60, 255)) + # Highlight + draw.ellipse([10, 14, 14, 20], fill=(80, 120, 220, 255)) + # Sparkle + draw.point((18, 16), fill=(200, 220, 255, 255)) + draw.point((17, 17), fill=(200, 220, 255, 255)) + + +def draw_item_sword(draw): + """Basic sword.""" + # Blade + draw.polygon([(15, 2), (18, 2), (18, 20), (15, 20)], fill=(180, 180, 200, 255)) + # Blade edge highlight + draw.line([(15, 2), (15, 20)], fill=(220, 220, 240, 255), width=1) + # Point + draw.polygon([(15, 2), (16.5, 0), (18, 2)], fill=(180, 180, 200, 255)) + # Guard + draw.rectangle([10, 20, 22, 23], fill=(140, 120, 60, 255)) + # Grip + draw.rectangle([14, 23, 18, 30], fill=(80, 60, 40, 255)) + # Grip wrap + draw.line([(14, 25), (18, 25)], fill=(100, 80, 50, 255), width=1) + draw.line([(14, 28), (18, 28)], fill=(100, 80, 50, 255), width=1) + + +def draw_item_shield(draw): + """Basic shield.""" + # Shield shape + draw.polygon( + [(16, 2), (26, 8), (26, 20), (16, 28), (6, 20), (6, 8)], fill=(100, 80, 60, 255) + ) + # Metal rim + draw.polygon( + [(16, 2), (26, 8), (26, 20), (16, 28), (6, 20), (6, 8)], + outline=(160, 140, 100, 255), + ) + # Center emblem + draw.ellipse([11, 11, 21, 21], fill=(140, 120, 80, 255)) + draw.ellipse([13, 13, 19, 19], fill=(180, 160, 100, 255)) + + +def draw_item_key(draw): + """Gold key.""" + # Key ring (top) + draw.ellipse([10, 4, 21, 15], fill=(200, 180, 60, 255), outline=(160, 140, 40, 255)) + draw.ellipse([13, 7, 18, 12], fill=(0, 0, 0, 0)) # Hole + # Key shaft + draw.rectangle([14, 14, 17, 26], fill=(200, 180, 60, 255)) + # Key teeth + draw.rectangle([17, 22, 22, 24], fill=(200, 180, 60, 255)) + draw.rectangle([17, 18, 20, 20], fill=(200, 180, 60, 255)) + + +def draw_item_gold(draw): + """Gold coins.""" + # Stack of coins + draw.ellipse([6, 18, 18, 26], fill=(180, 160, 40, 255)) + draw.ellipse([6, 16, 18, 24], fill=(200, 180, 60, 255)) + draw.ellipse([10, 12, 22, 20], fill=(180, 160, 40, 255)) + draw.ellipse([10, 10, 22, 18], fill=(200, 180, 60, 255)) + draw.ellipse([14, 6, 26, 14], fill=(180, 160, 40, 255)) + draw.ellipse([14, 4, 26, 12], fill=(220, 200, 80, 255)) + # $ symbol on top coin + draw.text((18, 4), "$", fill=(160, 140, 40, 255)) + + +# ============================================================================ +# Main +# ============================================================================ + + +def main(): + import os + + os.makedirs("sprites", exist_ok=True) + + # Terrain tiles + create_sprite(draw_floor, "tile_floor.png") + create_sprite(draw_wall, "tile_wall.png") + create_sprite(draw_void, "tile_void.png") + create_sprite(draw_water, "tile_water.png") + create_sprite(draw_custom, "tile_custom.png") + + # Actors + create_sprite(draw_player, "actor_player.png") + create_sprite(draw_enemy_goblin, "actor_goblin.png") + create_sprite(draw_enemy_skeleton, "actor_skeleton.png") + create_sprite(draw_enemy_slime, "actor_slime.png") + + # Props + create_sprite(draw_door_closed, "prop_door_closed.png") + create_sprite(draw_door_open, "prop_door_open.png") + create_sprite(draw_switch_off, "prop_switch_off.png") + create_sprite(draw_switch_on, "prop_switch_on.png") + create_sprite(draw_hazard, "prop_hazard.png") + + # Items + create_sprite(draw_item_potion_health, "item_potion_health.png") + create_sprite(draw_item_potion_mana, "item_potion_mana.png") + create_sprite(draw_item_sword, "item_sword.png") + create_sprite(draw_item_shield, "item_shield.png") + create_sprite(draw_item_key, "item_key.png") + create_sprite(draw_item_gold, "item_gold.png") + + print("\nAll sprites generated successfully!") + + +if __name__ == "__main__": + main() diff --git a/assets/sprites/actor_goblin.png b/assets/sprites/actor_goblin.png new file mode 100644 index 0000000..5127bab Binary files /dev/null and b/assets/sprites/actor_goblin.png differ diff --git a/assets/sprites/actor_player.png b/assets/sprites/actor_player.png new file mode 100644 index 0000000..50f3c32 Binary files /dev/null and b/assets/sprites/actor_player.png differ diff --git a/assets/sprites/actor_skeleton.png b/assets/sprites/actor_skeleton.png new file mode 100644 index 0000000..a4dc4e1 Binary files /dev/null and b/assets/sprites/actor_skeleton.png differ diff --git a/assets/sprites/actor_slime.png b/assets/sprites/actor_slime.png new file mode 100644 index 0000000..ab2d78f Binary files /dev/null and b/assets/sprites/actor_slime.png differ diff --git a/assets/sprites/item_gold.png b/assets/sprites/item_gold.png new file mode 100644 index 0000000..a8fef71 Binary files /dev/null and b/assets/sprites/item_gold.png differ diff --git a/assets/sprites/item_key.png b/assets/sprites/item_key.png new file mode 100644 index 0000000..4f388ab Binary files /dev/null and b/assets/sprites/item_key.png differ diff --git a/assets/sprites/item_potion_health.png b/assets/sprites/item_potion_health.png new file mode 100644 index 0000000..cdc7300 Binary files /dev/null and b/assets/sprites/item_potion_health.png differ diff --git a/assets/sprites/item_potion_mana.png b/assets/sprites/item_potion_mana.png new file mode 100644 index 0000000..41347fd Binary files /dev/null and b/assets/sprites/item_potion_mana.png differ diff --git a/assets/sprites/item_shield.png b/assets/sprites/item_shield.png new file mode 100644 index 0000000..b7252ea Binary files /dev/null and b/assets/sprites/item_shield.png differ diff --git a/assets/sprites/item_sword.png b/assets/sprites/item_sword.png new file mode 100644 index 0000000..2890481 Binary files /dev/null and b/assets/sprites/item_sword.png differ diff --git a/assets/sprites/prop_door_closed.png b/assets/sprites/prop_door_closed.png new file mode 100644 index 0000000..95d2ded Binary files /dev/null and b/assets/sprites/prop_door_closed.png differ diff --git a/assets/sprites/prop_door_open.png b/assets/sprites/prop_door_open.png new file mode 100644 index 0000000..708ab35 Binary files /dev/null and b/assets/sprites/prop_door_open.png differ diff --git a/assets/sprites/prop_hazard.png b/assets/sprites/prop_hazard.png new file mode 100644 index 0000000..61a1071 Binary files /dev/null and b/assets/sprites/prop_hazard.png differ diff --git a/assets/sprites/prop_switch_off.png b/assets/sprites/prop_switch_off.png new file mode 100644 index 0000000..d19ceec Binary files /dev/null and b/assets/sprites/prop_switch_off.png differ diff --git a/assets/sprites/prop_switch_on.png b/assets/sprites/prop_switch_on.png new file mode 100644 index 0000000..5232816 Binary files /dev/null and b/assets/sprites/prop_switch_on.png differ diff --git a/assets/sprites/tile_custom.png b/assets/sprites/tile_custom.png new file mode 100644 index 0000000..ee9e870 Binary files /dev/null and b/assets/sprites/tile_custom.png differ diff --git a/assets/sprites/tile_floor.png b/assets/sprites/tile_floor.png new file mode 100644 index 0000000..d043f2c Binary files /dev/null and b/assets/sprites/tile_floor.png differ diff --git a/assets/sprites/tile_void.png b/assets/sprites/tile_void.png new file mode 100644 index 0000000..acfb082 Binary files /dev/null and b/assets/sprites/tile_void.png differ diff --git a/assets/sprites/tile_wall.png b/assets/sprites/tile_wall.png new file mode 100644 index 0000000..f59d050 Binary files /dev/null and b/assets/sprites/tile_wall.png differ diff --git a/assets/sprites/tile_water.png b/assets/sprites/tile_water.png new file mode 100644 index 0000000..7dc1590 Binary files /dev/null and b/assets/sprites/tile_water.png differ diff --git a/contracts/move/.gitignore b/contracts/move/.gitignore new file mode 100644 index 0000000..813de75 --- /dev/null +++ b/contracts/move/.gitignore @@ -0,0 +1,4 @@ +build/* +traces/* +.trace +.coverage* diff --git a/contracts/move/ARCHITECTURE.md b/contracts/move/ARCHITECTURE.md new file mode 100644 index 0000000..4648425 --- /dev/null +++ b/contracts/move/ARCHITECTURE.md @@ -0,0 +1,385 @@ +# zkDungeon Move Contracts Architecture + +## Overview + +This document describes the Sui Move smart contract architecture for zkDungeon, a ZK-proof verified roguelike game that demonstrates **fairness without authority** and **secrecy without deceit**. + +## Core Principles + +1. **ZK Proof for State Transitions**: Every game state update is verified on-chain via Groth16 SNARKs +2. **Modular Challenge System**: Optional action logs enable competitive play and AI behavior verification +3. **Progressive Proof Submission**: Players choose proof frequency (every turn, every 100 turns, etc.) +4. **Content-Addressed Oracle**: Deterministic game content via Merkle commitments +5. **Off-chain Storage**: Full data stored in Walrus, only commitments on-chain + +## Module Architecture + +``` +dungeon/ +├── proof_verifier.move # Groth16 verification wrapper +├── game_session.move # Core game state management +└── action_log.move # Optional challenge/replay data +``` + +### Module Dependencies + +``` +action_log + ↓ +game_session + ↓ +proof_verifier + ↓ +sui::groth16 +``` + +## Module Details + +### 1. proof_verifier.move + +**Purpose**: Wraps Sui's native Groth16 verifier for game-specific proof verification. + +**Key Types**: +- `VerifyingKey`: Prepared verification key (from RISC0 Groth16 trusted setup) +- `PublicInputs`: Public values committed in ZK proof (8 field elements × 32 bytes) + +**Public Inputs Schema** (must match RISC0 guest program output): +1. `oracle_root` (32 bytes) - Game content commitment +2. `seed_commitment` (32 bytes) - RNG seed hash +3. `prev_state_root` (32 bytes) - State before actions +4. `prev_actions_root` (32 bytes) - Actions before this batch +5. `prev_nonce` (32 bytes, u64 padded) - Nonce before actions +6. `new_state_root` (32 bytes) - State after actions +7. `new_actions_root` (32 bytes) - Actions after this batch +8. `new_nonce` (32 bytes, u64 padded) - Nonce after actions + +**Critical Security Feature**: `actions_root` is included in public inputs to cryptographically bind actions to state transitions. Without this, a player could: +1. Play with manipulated AI (cheating) +2. Generate valid ZK proof with real actions +3. Submit fake "legitimate" actions to ActionLog +4. Pass challenge system verification + +**Functions**: +- `create_verifying_key()` - Initialize VK from RISC0 output +- `verify_game_proof()` - Verify Groth16 proof against public inputs +- `new_public_inputs()` - Construct PublicInputs from components + +--- + +### 2. game_session.move + +**Purpose**: Core game state management with progressive ZK proof verification. + +**Key Type**: +```move +public struct GameSession has key, store { + id: UID, + player: address, + + // Immutable context (set at creation) + oracle_root: vector, + initial_state_root: vector, + seed_commitment: vector, + + // Mutable state (updated by proofs) + state_root: vector, + actions_root: vector, + nonce: u64, + + finalized: bool, +} +``` + +**Design Decisions**: +- **No timestamps in struct**: Stored in events only (reduces storage costs, avoids non-deterministic ZK proof data) +- **Nonce instead of turn_count**: Matches codebase terminology +- **vector for roots**: Move doesn't support fixed-size arrays as struct fields +- **Owned object**: Players own their sessions, can transfer/delete them + +**Functions**: +- `create()` - Start new game session with commitments +- `update()` - Update state with ZK proof verification +- `finalize()` - Mark session complete (prevents further updates) +- `delete()` - Remove finalized session (storage rebate) + +**Update Flow**: +1. Player calls `update(session, vk, proof, new_state_root, new_actions_root, new_nonce)` +2. Validates ownership and finalization status +3. Constructs `PublicInputs` from current + new state +4. Calls `proof_verifier::verify_game_proof()` (aborts if invalid) +5. Updates session state +6. Emits `SessionUpdatedEvent` + +--- + +### 3. action_log.move + +**Purpose**: Optional module for storing action replay data, enabling competitive play and challenge verification. + +**Key Type**: +```move +public struct ActionLog has key, store { + id: UID, + session_id: address, // Reference to GameSession + player: address, + actions_blob_id: vector, // Walrus blob reference + actions_root: vector, // Must match GameSession.actions_root + finalized: bool, +} +``` + +**Design Rationale**: +- **Separated from GameSession**: Modular design allows: + - Private sessions (no ActionLog) - casual play + - Public sessions (with ActionLog) - competitive/verifiable play + - Independent module upgrades + - Gas optimization (players who don't care about challenges don't pay for unused fields) + +- **1:1 Relationship**: One ActionLog per GameSession (enforced by session_id reference) + +- **Actions Root Validation**: `publish()` and `update()` verify that `actions_root` matches the session's `actions_root` (which is ZK-verified) + +**Functions**: +- `publish()` - Create ActionLog linked to GameSession +- `update()` - Update with new Walrus blob reference +- `finalize()` - Mark log complete +- `delete()` - Remove finalized log + +**Validation Flow**: +1. Player calls `publish(session, actions_blob_id, actions_root)` +2. Validates ownership and session not finalized +3. **Critical**: Validates `actions_root == session.actions_root` +4. Creates ActionLog with Walrus blob reference +5. Emits `ActionLogPublishedEvent` + +**Why Separate from GameSession?**: +- **Modularity**: Challenge system is optional, not core to state verification +- **Upgradeability**: Challenge mechanics can evolve independently +- **Privacy**: Players can choose whether to publish actions +- **Gas Efficiency**: Non-competitive players don't pay for challenge infrastructure + +--- + +## Data Flow Architecture + +``` +Off-chain (Client) On-chain (Sui) +───────────────── ──────────────── + +Game Engine + ↓ +Execute Actions + ↓ +State Transitions + ↓ +Batch Actions + ↓ +Generate ZK Proof ──────────────→ GameSession.update() +(RISC0 STARK → Groth16) ↓ + Verify Proof + ↓ + Update State + +Upload to Walrus ───────────────→ ActionLog.publish() +(Full action data) ↓ + Validate actions_root + ↓ + Store blob reference +``` + +## Security Properties + +### 1. State Transition Integrity +- **Property**: Every state update is mathematically proven valid +- **Enforcement**: Groth16 verification in `GameSession.update()` +- **Guarantees**: No invalid moves, damage calculations, or rule violations + +### 2. Action-State Binding +- **Property**: Actions logged in ActionLog correspond to actual gameplay +- **Enforcement**: `actions_root` in ZK proof public inputs +- **Attack Prevention**: Cannot submit fake "legitimate" actions for challenges + +### 3. RNG Fairness +- **Property**: Random outcomes cannot be predicted or manipulated +- **Enforcement**: `seed_commitment` committed before game start +- **Guarantees**: Seed reveal verifies pre-commitment + +### 4. Oracle Integrity +- **Property**: Game content cannot change mid-game +- **Enforcement**: `oracle_root` immutable in GameSession +- **Guarantees**: Deterministic replay, content-addressed data + +### 5. Challenge System Integrity +- **Property**: AI behavior can be verified without revealing hidden information +- **Enforcement**: Full action log in Walrus + actions_root verification +- **Use Case**: Detect if player manipulated AI to play poorly + +## Challenge System Design (Future) + +The separated ActionLog module enables a future challenge system: + +### Challenge Flow +1. **Session Completion**: Player finalizes GameSession + ActionLog +2. **Challenge Submission**: Challenger posts bond, references ActionLog +3. **Data Retrieval**: Download full actions from Walrus via `actions_blob_id` +4. **Verification**: + - Compute actions root from downloaded data + - Compare with ActionLog.actions_root (ZK-verified) + - Replay actions, check AI behavior validity +5. **Resolution**: + - If actions valid: Challenger loses bond + - If actions invalid: Player penalized, challenger rewarded + +### Why Actions Root is Critical +Without `actions_root` in ZK proof, player could: +1. Play with modified AI (e.g., enemies always miss) +2. Generate valid proof (state transition is technically correct) +3. Upload fake "legitimate" actions to Walrus +4. Pass challenge verification (fake actions appear valid) + +**With** `actions_root` in proof: +1. ZK proof commits to specific action sequence +2. ActionLog must reference same action sequence +3. Any deviation detected during challenge verification + +## Storage Strategy + +### On-chain (Sui) +- **GameSession**: State commitments only (oracle_root, state_root, actions_root, seed_commitment) +- **ActionLog**: Walrus blob reference only (actions_blob_id) +- **Size**: ~200 bytes per session + ~100 bytes per log +- **Cost**: Minimal storage fees + +### Off-chain (Walrus) +- **Oracle Data**: Maps, items, NPCs, loot tables (JSON/CBOR) +- **Full Actions**: Complete action sequence (JSON/CBOR) +- **Full State** (optional): Checkpoints for faster replay +- **Size**: Megabytes of rich game data +- **Cost**: Decentralized storage fees + +### Why This Split? +- **Verification needs commitments**: Merkle roots are sufficient for ZK proofs +- **Challenges need full data**: Action replay requires complete action sequence +- **Gas optimization**: Only pay for on-chain commitments, not full data +- **Content addressing**: Walrus retrieval via blob ID, integrity verified via roots + +## Proof Generation Pipeline (Future Implementation) + +``` +Rust (game-core) RISC0 zkVM Sui Contract +──────────────── ─────────── ──────────── + +Execute actions + ↓ +Compute state delta + ↓ +Serialize inputs ─────────────→ Guest program + ↓ + Verify transitions + ↓ + Compute new roots + ↓ + Output PublicInputs ───→ GameSession.update() + ↓ ↓ + Generate STARK Verify Groth16 + ↓ ↓ + STARK → Groth16 Update state + (~200KB → ~200 bytes) +``` + +**RISC0 Guest Program** (to be implemented in `crates/zk/guest/`): +1. Read oracle_root, seed_commitment from public inputs +2. Deserialize initial state + action sequence +3. Execute actions using game-core engine +4. Verify state transition correctness +5. Compute new state_root, actions_root, nonce +6. Commit PublicInputs (8 field elements) +7. Generate STARK proof +8. Wrapper converts STARK → Groth16 (via `risc0_groth16::stark_to_snark`) + +## Development Roadmap + +### Phase 1: Contract Foundation ✅ +- [x] proof_verifier module with Groth16 wrapper +- [x] game_session module with state management +- [x] action_log module with Walrus integration +- [x] PublicInputs schema with actions_root + +### Phase 2: ZK Proof Pipeline (Next) +- [ ] RISC0 guest program matching PublicInputs schema +- [ ] Proof generation in ProverWorker (runtime) +- [ ] Groth16 wrapper integration (stark_to_snark) +- [ ] End-to-end test: client → proof → Sui verification + +### Phase 3: Walrus Integration +- [ ] Upload actions to Walrus after execution +- [ ] Store blob IDs in ActionLog +- [ ] Download and verify action data + +### Phase 4: Challenge System +- [ ] Challenge contract module +- [ ] Bond/penalty mechanism +- [ ] AI behavior verification logic +- [ ] Dispute resolution + +### Phase 5: Production Features +- [ ] Oracle registry for content versions +- [ ] Leaderboard contracts +- [ ] NFT rewards for achievements +- [ ] Gas optimization and security audit + +## Testing Strategy + +### Unit Tests (Not Implemented) +Per CLAUDE.md policy, no small unit tests in committed code. + +### Integration Tests (Future) +To be added in `contracts/move/tests/`: +- `test_session_lifecycle()` - Create, update, finalize, delete +- `test_proof_verification()` - Valid/invalid proof handling +- `test_action_log_validation()` - Actions root verification +- `test_ownership_enforcement()` - Access control +- `test_challenge_workflow()` - End-to-end challenge + +### Local Testing +```bash +# Build contracts +sui move build + +# Run tests (when implemented) +sui move test + +# Deploy to local network +sui client publish --gas-budget 100000000 +``` + +## Gas Optimization Notes + +1. **No timestamps in structs**: Reduces storage by 16 bytes per session +2. **u64 for nonce**: Cheaper than u256 (8 bytes vs 32 bytes on-chain) +3. **vector for roots**: Move's native dynamic type, no overhead +4. **Separate ActionLog**: Optional feature, players don't pay if not used +5. **Event-based indexing**: Off-chain indexers can track history without on-chain queries + +## Security Considerations + +1. **Proof verification is atomic**: Update only happens if proof is valid +2. **Ownership strictly enforced**: Only session owner can update/finalize/delete +3. **Finalization is one-way**: Cannot unfinalize, prevents replay attacks +4. **Actions root prevents spoofing**: Cryptographically bound to state transition +5. **Oracle immutability**: Cannot change game content mid-session + +## Known Limitations + +1. **Vector for roots**: Move doesn't support fixed-size arrays in structs (ergonomics limitation, no security impact) +2. **No on-chain RNG reveal verification**: Planned for Phase 4 +3. **No automated challenge resolution**: Manual verification for now +4. **Groth16 trusted setup**: Inherits RISC0's setup (industry standard, acceptable risk) + +## References + +- [Sui Move Documentation](https://docs.sui.io/concepts/sui-move-concepts) +- [Sui Groth16 Verifier](https://docs.sui.io/standards/cryptography/groth16) +- [RISC0 Documentation](https://dev.risczero.com/api) +- [Walrus Storage](https://docs.walrus.site/) +- [zkDungeon Codebase](../../../CLAUDE.md) diff --git a/contracts/move/Move.lock b/contracts/move/Move.lock new file mode 100644 index 0000000..dc41123 --- /dev/null +++ b/contracts/move/Move.lock @@ -0,0 +1,80 @@ +# @generated by Move, please check-in and do not edit manually. + +[move] +version = 3 +manifest_digest = "0BC32624AAB5852E56D17504D7AE7D1871EE5279A2830DCA062394DC6ADE75C9" +deps_digest = "397E6A9F7A624706DBDFEE056CE88391A15876868FD18A88504DA74EB458D697" +dependencies = [ + { id = "Bridge", name = "Bridge" }, + { id = "MoveStdlib", name = "MoveStdlib" }, + { id = "Sui", name = "Sui" }, + { id = "SuiSystem", name = "SuiSystem" }, + { id = "Walrus", name = "Walrus" }, +] + +[[move.package]] +id = "Bridge" +source = { git = "https://github.com/MystenLabs/sui.git", rev = "9a4d4016ba66c646c76c4b8d54fa9e767f240ab1", subdir = "crates/sui-framework/packages/bridge" } + +dependencies = [ + { id = "MoveStdlib", name = "MoveStdlib" }, + { id = "Sui", name = "Sui" }, + { id = "SuiSystem", name = "SuiSystem" }, +] + +[[move.package]] +id = "MoveStdlib" +source = { git = "https://github.com/MystenLabs/sui.git", rev = "9a4d4016ba66c646c76c4b8d54fa9e767f240ab1", subdir = "crates/sui-framework/packages/move-stdlib" } + +[[move.package]] +id = "Sui" +source = { git = "https://github.com/MystenLabs/sui.git", rev = "9a4d4016ba66c646c76c4b8d54fa9e767f240ab1", subdir = "crates/sui-framework/packages/sui-framework" } + +dependencies = [ + { id = "MoveStdlib", name = "MoveStdlib" }, +] + +[[move.package]] +id = "SuiSystem" +source = { git = "https://github.com/MystenLabs/sui.git", rev = "9a4d4016ba66c646c76c4b8d54fa9e767f240ab1", subdir = "crates/sui-framework/packages/sui-system" } + +dependencies = [ + { id = "MoveStdlib", name = "MoveStdlib" }, + { id = "Sui", name = "Sui" }, +] + +[[move.package]] +id = "WAL" +source = { git = "https://github.com/MystenLabs/walrus.git", rev = "main", subdir = "contracts/wal" } + +dependencies = [ + { id = "Sui", name = "Sui" }, +] + +[[move.package]] +id = "Walrus" +source = { git = "https://github.com/MystenLabs/walrus.git", rev = "main", subdir = "contracts/walrus" } + +dependencies = [ + { id = "Sui", name = "Sui" }, + { id = "WAL", name = "WAL" }, +] + +[move.toolchain-version] +compiler-version = "1.61.1" +edition = "2024.beta" +flavor = "sui" + +[env] + +[env.local] +chain-id = "dbb1d008" +original-published-id = "0xd0d4e08d544b58446e6a496e5eb2dad6893d9bec2dc11a1ebf72b456738fd752" +latest-published-id = "0xd0d4e08d544b58446e6a496e5eb2dad6893d9bec2dc11a1ebf72b456738fd752" +published-version = "1" + +[env.testnet] +chain-id = "4c78adac" +original-published-id = "0x810341a644478e2ccaddaaed014196c928fc1872ebdc37bbcfe972c6345dd993" +latest-published-id = "0x810341a644478e2ccaddaaed014196c928fc1872ebdc37bbcfe972c6345dd993" +published-version = "1" diff --git a/contracts/move/Move.toml b/contracts/move/Move.toml new file mode 100644 index 0000000..dd8632b --- /dev/null +++ b/contracts/move/Move.toml @@ -0,0 +1,25 @@ +[package] +name = "dungeon" +edition = "2024.beta" +authors = ["Wonjae Choi (wonjae@snu.ac.kr)"] + +[dependencies] +# Sui framework dependencies (Sui, MoveStdlib, etc.) are auto-added by default +Walrus = { git = "https://github.com/MystenLabs/walrus.git", rev = "main", subdir = "contracts/walrus" } + +[addresses] +dungeon = "0x0" + +# Named addresses will be accessible in Move as `@name`. They're also exported: +# for example, `std = "0x1"` is exported by the Standard Library. +# alice = "0xA11CE" + +[dev-dependencies] +# The dev-dependencies section allows overriding dependencies for `--test` and +# `--dev` modes. You can introduce test-only dependencies here. +# Local = { local = "../path/to/dev-build" } + +[dev-addresses] +# The dev-addresses section allows overwriting named addresses for the `--test` +# and `--dev` modes. +# alice = "0xB0B" diff --git a/contracts/move/sources/game_session.move b/contracts/move/sources/game_session.move new file mode 100644 index 0000000..b1c65de --- /dev/null +++ b/contracts/move/sources/game_session.move @@ -0,0 +1,520 @@ +/// Game Session Module +/// +/// Manages stateful on-chain game sessions with progressive ZK proof verification. +/// Each session tracks state commitments (oracle, state, actions) that are updated +/// via zero-knowledge proofs, enabling verifiable off-chain gameplay. +/// +/// # Design +/// - Sessions are owned objects that track game state commitments +/// - Progressive updates via ZK proofs (players choose proof frequency) +/// - Content-addressed oracle data (deterministic replay) +/// - Optimistic gameplay with challenge period for verification +/// - Multiple action logs stored via Dynamic Object Fields during challenge period +/// - Events emitted for all state transitions +/// +/// # Challenge-Based Verification +/// - Players submit ZK proofs with action logs published to Walrus +/// - Anyone can download actions and challenge invalid gameplay during challenge period +/// - Actions root in ZK proof cryptographically binds published actions to verified state +/// - Multiple updates can occur during challenge period (each stored separately) +/// - Old action logs can be cleaned up after challenge period expires +/// - Enables trustless verification without authority signatures +module dungeon::game_session { + use sui::event; + use sui::dynamic_object_field as dof; + use walrus::blob::Blob; + + // ===== Error Codes ===== + + /// Caller is not the session owner + const ENotOwner: u64 = 1; + /// Session is not finalized yet + const ENotFinalized: u64 = 2; + /// Action log blob does not exist + const EActionLogNotFound: u64 = 3; + /// Challenge period has not expired yet + const EChallengeNotExpired: u64 = 4; + /// Action logs must be cleaned up before finalization + const EActionLogsRemaining: u64 = 5; + + // ===== Constants ===== + + /// Challenge period duration in epochs (e.g., 7 days worth of epochs) + /// After this period, action logs can be cleaned up + const CHALLENGE_PERIOD_EPOCHS: u64 = 7 * 24 * 60; // ~7 days (assuming 1 epoch = 1 minute) + + // ===== Structs ===== + + /// Represents an active game session + public struct GameSession has key, store { + id: UID, + /// Player address (session owner) + player: address, + + // Immutable context (set at creation) + /// Oracle data commitment (content hash) + oracle_root: vector, + /// Initial state root at game start + initial_state_root: vector, + /// Seed commitment for RNG fairness + seed_commitment: vector, + + // Mutable state (updated by proofs) + /// Current game state root + state_root: vector, + /// Action execution nonce (incremented after each action) + nonce: u64, + /// Number of pending action logs awaiting cleanup + pending_action_logs: u64, + + // Status + /// Whether the session is finalized + finalized: bool, + } + + /// Wrapper for action log blob with metadata + /// Stored as Dynamic Object Field child of GameSession + /// Key: nonce (u64) + /// The blob_id serves as the cryptographic commitment to the actions + public struct ActionLogBlob has key, store { + id: UID, + /// Walrus blob containing the full action sequence + blob: Blob, + /// Epoch when this action log was submitted + submitted_at: u64, + /// State root at the beginning of this action batch (for fraud proof verification) + start_state_root: vector, + } + + // ===== Events ===== + + /// Emitted when a new game session is started + public struct SessionStartedEvent has copy, drop { + session_id: address, + player: address, + oracle_root: vector, + started_at: u64, + } + + /// Emitted when session state is updated via ZK proof + public struct SessionUpdatedEvent has copy, drop { + session_id: address, + new_state_root: vector, + nonce: u64, + updated_at: u64, + } + + /// Emitted when a game session is finalized + public struct SessionFinalizedEvent has copy, drop { + session_id: address, + final_state_root: vector, + final_nonce: u64, + finalized_at: u64, + } + + /// Emitted when an action log is published or updated + public struct ActionLogPublishedEvent has copy, drop { + session_id: address, + actions_blob_id: u256, + nonce: u64, + published_at: u64, + } + + // ===== Public Functions ===== + + /// Create a new game session + /// + /// Initializes a new GameSession object with the provided commitments + /// and transfers it to the transaction sender. + /// + /// # Arguments + /// * `oracle_root` - Content hash of oracle data (maps, items, NPCs, etc.) + /// * `initial_state_root` - Merkle root of initial game state + /// * `seed_commitment` - Commitment to RNG seed (hash of seed) + /// * `ctx` - Transaction context + /// + /// # Events + /// Emits `SessionStartedEvent` with session details + entry fun create( + oracle_root: vector, + initial_state_root: vector, + seed_commitment: vector, + ctx: &mut TxContext, + ) { + let session_id = object::new(ctx); + let player = tx_context::sender(ctx); + + let session = GameSession { + id: session_id, + player, + oracle_root, + initial_state_root, + seed_commitment, + state_root: initial_state_root, + nonce: 0, + pending_action_logs: 0, + finalized: false, + }; + + event::emit(SessionStartedEvent { + session_id: session_id(&session), + player, + oracle_root, + started_at: tx_context::epoch(ctx), + }); + + transfer::public_transfer(session, player); + } + + /// Update session state with action log + /// + /// TODO: Add ZK proof verification when VK format is resolved. + /// The ZK proof should verify: + /// - Transition from prev_state_root to new_state_root is valid + /// - Actions executed match the Walrus blob (blob_id == actions_root) + /// - All game rules were correctly enforced + /// - Oracle commitment matches the session's oracle_root + /// + /// If the session was previously finalized, this will unfinalize it + /// (since new action logs require a new challenge period). + /// + /// # Arguments + /// * `session` - Mutable reference to GameSession + /// * `new_state_root` - New game state root after executing actions + /// * `new_nonce` - Updated nonce (incremented after each action) + /// * `actions_blob` - Walrus blob containing full action sequence + /// * `ctx` - Transaction context (for sender and epoch) + /// + /// # Aborts + /// * `ENotOwner` - If caller is not the session owner + /// + /// # Events + /// Emits `SessionUpdatedEvent` and `ActionLogPublishedEvent` + public fun update( + session: &mut GameSession, + new_state_root: vector, + new_nonce: u64, + actions_blob: Blob, + ctx: &mut TxContext, + ) { + // Validate ownership + assert!(tx_context::sender(ctx) == session.player, ENotOwner); + + // Get blob_id which serves as actions_root + let blob_id = walrus::blob::blob_id(&actions_blob); + + // TODO: Add ZK proof verification here + // When verification is enabled, this function should accept: + // - vk: &VerifyingKey (or extract from global registry) + // - proof: vector + // - journal_digest: vector + // + // Then verify: + // let actions_root = u256_to_bytes(blob_id); + // let journal_data = proof_verifier::new_journal_data( + // session.oracle_root, + // session.seed_commitment, + // session.state_root, + // actions_root, + // new_state_root, + // new_nonce, + // ); + // proof_verifier::verify_game_proof(vk, journal_digest, &journal_data, proof); + + // Create action log blob wrapper with metadata + let action_log = ActionLogBlob { + id: object::new(ctx), + blob: actions_blob, + submitted_at: tx_context::epoch(ctx), + start_state_root: session.state_root, + }; + + // Store action log as Dynamic Object Field using nonce as key + dof::add( + &mut session.id, + new_nonce, + action_log + ); + + // Update session state + session.state_root = new_state_root; + session.nonce = new_nonce; + session.pending_action_logs = session.pending_action_logs + 1; + + // Unfinalize if previously finalized (new action logs require challenge period) + if (session.finalized) { + session.finalized = false; + }; + + // Emit events + event::emit(ActionLogPublishedEvent { + session_id: session_id(session), + actions_blob_id: blob_id, + nonce: new_nonce, + published_at: tx_context::epoch(ctx), + }); + + event::emit(SessionUpdatedEvent { + session_id: session_id(session), + new_state_root, + nonce: new_nonce, + updated_at: tx_context::epoch(ctx), + }); + } + + /// Remove expired action logs after challenge period + /// + /// Removes action log blobs that have passed the challenge period, freeing up + /// storage and providing storage rebate. Can be called by anyone (not just owner) + /// to incentivize cleanup. + /// + /// The challenge period is defined by CHALLENGE_PERIOD_EPOCHS constant. + /// This function removes the ActionLogBlob wrappers and returns the Walrus Blobs. + /// + /// For single nonce removal, pass a single-element vector: `vector[nonce]`. + /// If any action log hasn't expired or doesn't exist, the entire transaction aborts. + /// + /// # Arguments + /// * `session` - Mutable reference to GameSession + /// * `nonces` - Vector of nonces to remove (action logs must be expired) + /// * `ctx` - Transaction context (for current epoch) + /// + /// # Returns + /// Vector of Walrus Blob objects (in same order as input nonces) + /// + /// # Aborts + /// * `EActionLogNotFound` - If any action log doesn't exist + /// * `EChallengeNotExpired` - If any action log hasn't expired yet + public fun remove_expired_action_logs( + session: &mut GameSession, + nonces: vector, + ctx: &TxContext, + ): vector { + let mut results = vector::empty(); + let mut i = 0; + let len = vector::length(&nonces); + + while (i < len) { + let nonce = *vector::borrow(&nonces, i); + + // Check if action log exists + assert!(dof::exists_(&session.id, nonce), EActionLogNotFound); + + // Borrow to check expiration + let action_log = dof::borrow(&session.id, nonce); + let current_epoch = tx_context::epoch(ctx); + let challenge_expiry = action_log.submitted_at + CHALLENGE_PERIOD_EPOCHS; + + assert!(current_epoch >= challenge_expiry, EChallengeNotExpired); + + // Remove and unwrap + let action_log = dof::remove(&mut session.id, nonce); + let ActionLogBlob { id, blob, submitted_at: _, start_state_root: _ } = action_log; + object::delete(id); + + vector::push_back(&mut results, blob); + i = i + 1; + }; + + // Decrement counter by the number of removed logs + session.pending_action_logs = session.pending_action_logs - len; + + results + } + + /// Finalize the game session + /// + /// Marks the session as finalized, preventing further updates. + /// This is typically called when the game is complete (player died or won). + /// + /// All action logs must be cleaned up before finalization to ensure + /// all challenge periods have expired and verification is complete. + /// + /// # Arguments + /// * `session` - Mutable reference to GameSession + /// * `ctx` - Transaction context (for sender verification) + /// + /// # Aborts + /// * `ENotOwner` - If caller is not the session owner + /// * `EActionLogsRemaining` - If there are pending action logs that haven't been cleaned up + /// + /// # Events + /// Emits `SessionFinalizedEvent` with final state and turn count + public fun finalize( + session: &mut GameSession, + ctx: &TxContext, + ) { + // Check ownership + assert!(tx_context::sender(ctx) == session.player, ENotOwner); + + // Ensure all action logs have been cleaned up + assert!(session.pending_action_logs == 0, EActionLogsRemaining); + + // Mark as finalized + session.finalized = true; + + event::emit(SessionFinalizedEvent { + session_id: session_id(session), + final_state_root: session.state_root, + final_nonce: session.nonce, + finalized_at: tx_context::epoch(ctx), + }); + } + + /// Delete a finalized game session + /// + /// Removes the session from blockchain storage, freeing resources and providing + /// storage rebate to the caller. Only finalized sessions can be deleted, and only + /// by their owner. + /// + /// This is useful for cleaning up completed game sessions that are no longer needed, + /// reducing storage costs. Important sessions (e.g., high scores) can be kept on-chain + /// for historical records and leaderboards. + /// + /// # Arguments + /// * `session` - The session to delete (ownership transferred, will be consumed) + /// * `ctx` - Transaction context (for sender verification) + /// + /// # Aborts + /// * `ENotFinalized` - If session is not finalized yet + /// * `ENotOwner` - If caller is not the session owner + public fun delete(session: GameSession, ctx: &TxContext) { + // Validate session is finalized + assert!(session.finalized, ENotFinalized); + + // Validate ownership + assert!(tx_context::sender(ctx) == session.player, ENotOwner); + + // Destructure session and delete + let GameSession { + id, + player: _, + oracle_root: _, + initial_state_root: _, + seed_commitment: _, + state_root: _, + nonce: _, + pending_action_logs: _, + finalized: _, + } = session; + + object::delete(id); + } + + // ===== View Functions ===== + + /// Get the session's object ID as address + /// + /// Returns the unique identifier for this session as an address. + /// Useful for event tracking and referencing sessions. + /// + /// # Arguments + /// * `session` - Reference to GameSession + /// + /// # Returns + /// Address representation of the session's UID + public fun session_id(session: &GameSession): address { + object::uid_to_address(&session.id) + } + + /// Get the session owner's address + public fun player(session: &GameSession): address { + session.player + } + + /// Borrow the oracle root commitment + public fun borrow_oracle_root(session: &GameSession): &vector { + &session.oracle_root + } + + /// Borrow the current state root + public fun borrow_state_root(session: &GameSession): &vector { + &session.state_root + } + + /// Get the current nonce (action execution count) + public fun nonce(session: &GameSession): u64 { + session.nonce + } + + /// Get the number of pending action logs awaiting cleanup + public fun pending_action_logs(session: &GameSession): u64 { + session.pending_action_logs + } + + /// Check if the session is finalized + public fun is_finalized(session: &GameSession): bool { + session.finalized + } + + /// Check if an action log exists for a given nonce + /// + /// Use this to verify if a specific action log is available for challenge verification. + /// + /// # Arguments + /// * `session` - Reference to GameSession + /// * `nonce` - Nonce of the action log to check + /// + /// # Returns + /// True if action log exists, false otherwise + public fun has_action_log(session: &GameSession, nonce: u64): bool { + dof::exists_(&session.id, nonce) + } + + /// Borrow an action log blob for a specific nonce + /// + /// Returns a reference to the ActionLogBlob containing the Walrus blob ID and metadata. + /// Use this for challenge validation and verification. + /// + /// # Arguments + /// * `session` - Reference to GameSession + /// * `nonce` - Nonce of the action log to borrow + /// + /// # Returns + /// Reference to ActionLogBlob + /// + /// # Aborts + /// * `EActionLogNotFound` - If action log with given nonce doesn't exist + public fun borrow_action_log(session: &GameSession, nonce: u64): &ActionLogBlob { + assert!(dof::exists_(&session.id, nonce), EActionLogNotFound); + dof::borrow(&session.id, nonce) + } + + /// Get the blob ID from an ActionLogBlob + /// + /// Extracts the Walrus blob ID for downloading action sequence. + /// + /// # Arguments + /// * `action_log` - Reference to ActionLogBlob + /// + /// # Returns + /// Blob ID as u256 + public fun action_log_blob_id(action_log: &ActionLogBlob): u256 { + walrus::blob::blob_id(&action_log.blob) + } + + /// Get submission epoch from action log + public fun action_log_submitted_at(action_log: &ActionLogBlob): u64 { + action_log.submitted_at + } + + /// Get the start state root from action log (for fraud proof verification) + public fun action_log_start_state_root(action_log: &ActionLogBlob): &vector { + &action_log.start_state_root + } + + /// Get the initial state root (for replay verification) + public fun borrow_initial_state_root(session: &GameSession): &vector { + &session.initial_state_root + } + + /// Get the seed commitment (for RNG verification) + public fun borrow_seed_commitment(session: &GameSession): &vector { + &session.seed_commitment + } + + /// Get the challenge period duration in epochs + public fun challenge_period_epochs(): u64 { + CHALLENGE_PERIOD_EPOCHS + } +} diff --git a/contracts/move/sources/proof_verifier.move b/contracts/move/sources/proof_verifier.move new file mode 100644 index 0000000..f6c9bae --- /dev/null +++ b/contracts/move/sources/proof_verifier.move @@ -0,0 +1,421 @@ +/// Proof Verification Module - RISC0 Groth16 Compatible +/// +/// Implements two-stage verification for ZK proofs of game state transitions. +/// +/// # RISC0 Groth16 Architecture +/// +/// RISC0's Groth16 wrapper only exposes 3 public inputs: +/// 1. CONTROL_ROOT - RISC0 control root +/// 2. CLAIM_DIGEST - Hash of execution claim (contains IMAGE_ID and JOURNAL_DIGEST) +/// 3. CONTROL_ID - Control identifier +/// +/// The journal_digest (SHA-256 of journal bytes) is embedded in CLAIM_DIGEST, +/// NOT directly accessible as a Groth16 public input. +/// +/// # Two-Stage Verification +/// +/// **Stage 1 - Groth16 Proof Verification:** +/// - Verify the cryptographic proof (seal) is valid +/// - Verify journal_digest matches the proof's committed value +/// - This proves: "Some valid execution produced this journal digest" +/// +/// **Stage 2 - Journal Content Verification:** +/// - Receive 168-byte journal data from caller +/// - Verify: SHA-256(journal_data) == journal_digest +/// - Extract and validate 6 fields from journal +/// - This proves: "The journal contains these specific committed values" +/// +/// # Journal Structure (168 bytes) +/// +/// The guest program commits 6 fields to the journal in exact order: +/// ``` +/// 1. oracle_root (32 bytes, offset 0..32) - Static game content commitment +/// 2. seed_commitment (32 bytes, offset 32..64) - RNG seed commitment +/// 3. prev_state_root (32 bytes, offset 64..96) - State before execution +/// 4. actions_root (32 bytes, offset 96..128) - Action sequence (Walrus blob_id) +/// 5. new_state_root (32 bytes, offset 128..160) - State after execution +/// 6. new_nonce (8 bytes, offset 160..168) - Action counter (u64 little-endian) +/// ``` +/// +/// Total: 168 bytes (5 × 32 + 8) +/// +/// # Design Rationale +/// +/// This two-stage approach is required because RISC0 Groth16 wrapper does not +/// expose individual journal fields as public inputs. Instead, it only exposes +/// the journal digest. This design: +/// - ✅ Maintains full RISC0 compatibility +/// - ✅ Preserves all 6 fields as verifiable data +/// - ✅ Minimal gas overhead (one SHA-256 + comparison) +/// - ✅ Clean separation: cryptographic proof vs data validation +/// +/// Tradeoff: Journal data (168 bytes) must be included in transaction calldata +module dungeon::proof_verifier { + use sui::groth16; + use std::hash; + + // ===== Error Codes ===== + + /// Invalid proof - Groth16 verification failed + const EInvalidProof: u64 = 1; + /// Journal digest mismatch - provided journal doesn't hash to expected digest + const EJournalMismatch: u64 = 2; + /// Invalid journal format - wrong size or structure + const EInvalidJournal: u64 = 3; + + // ===== Constants ===== + + /// Expected journal size in bytes (5 × 32 + 8) + const JOURNAL_SIZE: u64 = 168; + + // ===== Structs ===== + + /// Prepared verifying key for Groth16 proof verification + /// + /// This key is prepared once and stored on-chain for reuse. + /// It corresponds to the RISC0 game guest program's circuit. + public struct VerifyingKey has key, store { + id: UID, + /// Prepared verifying key for efficient verification + prepared_vk: groth16::PreparedVerifyingKey, + /// Version/identifier for the game circuit + version: u64, + } + + /// Journal data structure - matches guest program output (168 bytes) + /// + /// This struct represents the parsed journal committed by the RISC0 guest program. + /// All fields are cryptographically committed via the journal_digest. + public struct JournalData has copy, drop, store { + /// Oracle data commitment (32 bytes) - SHA-256 of OracleSnapshot + oracle_root: vector, + /// Seed commitment for RNG (32 bytes) - SHA-256 of game_seed + seed_commitment: vector, + /// Previous state root (32 bytes) - SHA-256 of GameState before execution + prev_state_root: vector, + /// Actions root (32 bytes) - Walrus blob_id or SHA-256 of action sequence + /// For single action: all zeros (no batch) + /// For batch: actual Walrus blob_id or hash commitment + actions_root: vector, + /// New state root (32 bytes) - SHA-256 of GameState after execution + new_state_root: vector, + /// New nonce (8 bytes, u64) - Action counter after execution + new_nonce: u64, + } + + // ===== Admin Functions ===== + + /// Initialize a new verifying key as a shared object + /// + /// This should be called once to prepare the verifying key for the game circuit. + /// The verifying key comes from the RISC0 Groth16 trusted setup. + /// The created VerifyingKey is shared globally so all users can verify proofs. + /// + /// # Arguments + /// * `vk_bytes` - Raw verifying key bytes from RISC0 + /// * `version` - Circuit version identifier + /// * `ctx` - Transaction context + entry fun create_verifying_key( + vk_bytes: vector, + version: u64, + ctx: &mut TxContext, + ) { + let curve = groth16::bn254(); + let prepared_vk = groth16::prepare_verifying_key(&curve, &vk_bytes); + + let vk = VerifyingKey { + id: object::new(ctx), + prepared_vk, + version, + }; + + // Share the VK so everyone can use it for proof verification + transfer::share_object(vk); + } + + // ===== Public Functions ===== + + /// Verify a game state transition proof with two-stage verification + /// + /// **Stage 1:** Verify Groth16 proof with journal_digest as public input + /// **Stage 2:** Verify journal_data hashes to journal_digest and extract fields + /// + /// This function combines both stages for convenience. For gas optimization, + /// you can use `verify_groth16` and `verify_journal` separately. + /// + /// # Arguments + /// * `vk` - Prepared verifying key + /// * `journal_digest` - SHA-256 hash of journal (32 bytes) - the Groth16 public input + /// * `journal_data` - Actual journal content (168 bytes) + /// * `proof_bytes` - Groth16 proof bytes (seal) + /// + /// # Returns + /// Parsed JournalData if verification succeeds + /// + /// # Aborts + /// * `EInvalidProof` - If Groth16 proof verification fails + /// * `EJournalMismatch` - If journal doesn't hash to expected digest + /// * `EInvalidJournal` - If journal format is invalid + public fun verify_game_proof( + vk: &VerifyingKey, + journal_digest: vector, + journal_data: &JournalData, + proof_bytes: vector, + ): JournalData { + // Stage 1: Verify Groth16 proof with journal_digest + verify_groth16(vk, journal_digest, proof_bytes); + + // Stage 2: Verify journal content matches digest + verify_journal(journal_digest, journal_data); + + // Return parsed journal data + *journal_data + } + + /// Stage 1: Verify Groth16 proof with journal_digest as public input + /// + /// Verifies that the cryptographic proof is valid for the given journal digest. + /// + /// # Arguments + /// * `vk` - Prepared verifying key + /// * `journal_digest` - SHA-256 hash of journal (32 bytes) + /// * `proof_bytes` - Groth16 proof bytes (seal) + /// + /// # Aborts + /// * `EInvalidProof` - If proof verification fails + public fun verify_groth16( + vk: &VerifyingKey, + journal_digest: vector, + proof_bytes: vector, + ) { + // Create proof points from bytes + let curve = groth16::bn254(); + let proof_points = groth16::proof_points_from_bytes(proof_bytes); + + // Public input is just the journal digest (32 bytes) + let public_inputs = groth16::public_proof_inputs_from_bytes(journal_digest); + + // Verify Groth16 proof + let valid = groth16::verify_groth16_proof( + &curve, + &vk.prepared_vk, + &public_inputs, + &proof_points, + ); + + assert!(valid, EInvalidProof); + } + + /// Stage 2: Verify journal content matches digest and validate structure + /// + /// Verifies that: + /// 1. Provided journal data hashes to the expected journal_digest + /// 2. Journal structure is valid (168 bytes with correct field layout) + /// + /// # Arguments + /// * `expected_digest` - Expected SHA-256 hash of journal + /// * `journal_data` - Journal data to verify + /// + /// # Aborts + /// * `EJournalMismatch` - If computed digest doesn't match expected + public fun verify_journal( + expected_digest: vector, + journal_data: &JournalData, + ) { + // Compute digest of provided journal data + let computed_digest = compute_journal_digest(journal_data); + + // Verify digest matches + assert!(computed_digest == expected_digest, EJournalMismatch); + } + + // ===== Helper Functions ===== + + /// Compute SHA-256 digest of journal data + /// + /// Serializes journal fields in exact order matching guest program: + /// 1. oracle_root (32 bytes) + /// 2. seed_commitment (32 bytes) + /// 3. prev_state_root (32 bytes) + /// 4. actions_root (32 bytes) + /// 5. new_state_root (32 bytes) + /// 6. new_nonce (8 bytes, u64 little-endian) + /// + /// Total: 168 bytes → SHA-256 → 32 bytes digest + fun compute_journal_digest(journal: &JournalData): vector { + let mut bytes = vector::empty(); + + // 1. Oracle root (32 bytes) + vector::append(&mut bytes, journal.oracle_root); + + // 2. Seed commitment (32 bytes) + vector::append(&mut bytes, journal.seed_commitment); + + // 3. Previous state root (32 bytes) + vector::append(&mut bytes, journal.prev_state_root); + + // 4. Actions root (32 bytes) + vector::append(&mut bytes, journal.actions_root); + + // 5. New state root (32 bytes) + vector::append(&mut bytes, journal.new_state_root); + + // 6. New nonce (8 bytes, u64 little-endian) + vector::append(&mut bytes, u64_to_bytes_le(journal.new_nonce)); + + // Verify total size is 168 bytes + assert!(vector::length(&bytes) == JOURNAL_SIZE, EInvalidJournal); + + // Compute SHA-256 (sha2_256 from std::hash) + hash::sha2_256(bytes) + } + + /// Convert u64 to 8-byte array (little-endian) + /// + /// This matches the Rust `u64::to_le_bytes()` serialization used in + /// the guest program and host prover. + fun u64_to_bytes_le(value: u64): vector { + let mut bytes = vector::empty(); + + // Extract 8 bytes in little-endian order + let mut v = value; + let mut i = 0; + while (i < 8) { + vector::push_back(&mut bytes, ((v & 0xFF) as u8)); + v = v >> 8; + i = i + 1; + }; + + bytes + } + + // ===== Constructor Functions ===== + + /// Create journal data from raw 168-byte vector + /// + /// Parses a raw journal byte vector into structured JournalData. + /// Useful when receiving journal from off-chain or storage. + /// + /// # Arguments + /// * `journal_bytes` - Raw journal bytes (must be exactly 168 bytes) + /// + /// # Returns + /// Parsed JournalData + /// + /// # Aborts + /// * `EInvalidJournal` - If size is not 168 bytes + public fun parse_journal_bytes(journal_bytes: vector): JournalData { + // Verify size + assert!(vector::length(&journal_bytes) == JOURNAL_SIZE, EInvalidJournal); + + // Extract fields in order (matching offsets from documentation) + let oracle_root = vector_slice(&journal_bytes, 0, 32); + let seed_commitment = vector_slice(&journal_bytes, 32, 64); + let prev_state_root = vector_slice(&journal_bytes, 64, 96); + let actions_root = vector_slice(&journal_bytes, 96, 128); + let new_state_root = vector_slice(&journal_bytes, 128, 160); + let new_nonce = bytes_to_u64_le(&journal_bytes, 160); + + JournalData { + oracle_root, + seed_commitment, + prev_state_root, + actions_root, + new_state_root, + new_nonce, + } + } + + /// Create journal data from individual field components + /// + /// # Arguments + /// * `oracle_root` - Oracle data commitment (32 bytes) + /// * `seed_commitment` - RNG seed commitment (32 bytes) + /// * `prev_state_root` - Previous state root (32 bytes) + /// * `actions_root` - Actions commitment (32 bytes) + /// * `new_state_root` - New state root (32 bytes) + /// * `new_nonce` - New nonce (u64) + /// + /// # Returns + /// JournalData struct + public fun new_journal_data( + oracle_root: vector, + seed_commitment: vector, + prev_state_root: vector, + actions_root: vector, + new_state_root: vector, + new_nonce: u64, + ): JournalData { + JournalData { + oracle_root, + seed_commitment, + prev_state_root, + actions_root, + new_state_root, + new_nonce, + } + } + + // ===== View Functions ===== + + /// Get the verifying key version + public fun verifying_key_version(vk: &VerifyingKey): u64 { + vk.version + } + + /// Borrow oracle root from journal data + public fun oracle_root(journal: &JournalData): &vector { + &journal.oracle_root + } + + /// Borrow seed commitment from journal data + public fun seed_commitment(journal: &JournalData): &vector { + &journal.seed_commitment + } + + /// Borrow previous state root from journal data + public fun prev_state_root(journal: &JournalData): &vector { + &journal.prev_state_root + } + + /// Borrow actions root from journal data (Walrus blob_id) + public fun actions_root(journal: &JournalData): &vector { + &journal.actions_root + } + + /// Borrow new state root from journal data + public fun new_state_root(journal: &JournalData): &vector { + &journal.new_state_root + } + + /// Get new nonce from journal data + public fun new_nonce(journal: &JournalData): u64 { + journal.new_nonce + } + + // ===== Internal Helper Functions ===== + + /// Extract a slice from a vector (inclusive start, exclusive end) + fun vector_slice(vec: &vector, start: u64, end: u64): vector { + let mut result = vector::empty(); + let mut i = start; + while (i < end) { + vector::push_back(&mut result, *vector::borrow(vec, i)); + i = i + 1; + }; + result + } + + /// Convert 8 bytes to u64 (little-endian) starting at offset + fun bytes_to_u64_le(bytes: &vector, offset: u64): u64 { + let mut result: u64 = 0; + let mut i: u64 = 0; + while (i < 8) { + let byte = (*vector::borrow(bytes, offset + i) as u64); + let shift = ((i * 8) as u8); + result = result | (byte << shift); + i = i + 1; + }; + result + } +} diff --git a/contracts/move/tests/contracts_tests.move b/contracts/move/tests/contracts_tests.move new file mode 100644 index 0000000..1fc136b --- /dev/null +++ b/contracts/move/tests/contracts_tests.move @@ -0,0 +1,18 @@ +/* +#[test_only] +module contracts::contracts_tests; +// uncomment this line to import the module +// use contracts::contracts; + +const ENotImplemented: u64 = 0; + +#[test] +fun test_contracts() { + // pass +} + +#[test, expected_failure(abort_code = ::contracts::contracts_tests::ENotImplemented)] +fun test_contracts_fail() { + abort ENotImplemented +} +*/ diff --git a/crates/client/Cargo.toml b/crates/client/Cargo.toml new file mode 100644 index 0000000..1c5242d --- /dev/null +++ b/crates/client/Cargo.toml @@ -0,0 +1,58 @@ +[package] +name = "dungeon-client" +version = "0.1.0" +edition = "2024" + +# This crate is both a library (Client orchestration) and a binary (entry point) +[lib] +name = "dungeon_client" +path = "src/lib.rs" + +[[bin]] +name = "dungeon" +path = "src/main.rs" + +[features] +default = [] + +# Frontend +cli = ["dep:client-frontend-cli"] +bevy = ["dep:client-frontend-bevy"] + +# Blockchain (optional) +sui = ["dep:client-blockchain-sui", "client-bootstrap/sui", "client-frontend-cli?/sui"] +# ethereum = [] # Future + +# ZK Backend (mutually exclusive - choose ONE) +risc0 = ["zk/risc0", "client-frontend-cli?/risc0", "client-frontend-bevy?/risc0", "client-blockchain-sui?/risc0"] +sp1 = ["zk/sp1", "client-frontend-cli?/sp1", "client-frontend-bevy?/sp1", "client-blockchain-sui?/sp1"] +stub = ["zk/stub", "client-frontend-cli?/stub", "client-frontend-bevy?/stub", "client-blockchain-sui?/stub"] +arkworks = ["zk/arkworks", "client-frontend-cli?/arkworks", "client-frontend-bevy?/arkworks", "client-blockchain-sui?/arkworks"] + +[dependencies] +# Core dependencies +anyhow = { workspace = true } +tokio = { workspace = true } +dotenvy = { workspace = true } +tracing = { workspace = true } +tracing-subscriber = { workspace = true } +async-trait = { workspace = true } + +# Runtime (always required for Client) +runtime = { workspace = true } + +# ZK proving (for proof data types) +zk = { workspace = true } + +# Bootstrap (for RuntimeBuilder, used in main.rs) +client-bootstrap = { workspace = true } + +# Frontend core (for shared types) +client-frontend-core = { workspace = true } + +# Feature-gated frontends +client-frontend-cli = { workspace = true, optional = true } +client-frontend-bevy = { workspace = true, optional = true } + +# Blockchain integration (optional) +client-blockchain-sui = { workspace = true, optional = true } diff --git a/crates/client/blockchain/sui/Cargo.toml b/crates/client/blockchain/sui/Cargo.toml new file mode 100644 index 0000000..ec2ba57 --- /dev/null +++ b/crates/client/blockchain/sui/Cargo.toml @@ -0,0 +1,55 @@ +[package] +name = "client-blockchain-sui" +version = "0.1.0" +edition = "2024" + +[features] +default = [] + +# ZK backend propagation (required by zk dependency) +risc0 = ["zk/risc0"] +sp1 = ["zk/sp1"] +stub = ["zk/stub"] +arkworks = ["zk/arkworks"] + +[dependencies] +# Internal dependencies +zk = { workspace = true } + +# Sui SDK +sui-sdk = { git = "https://github.com/mystenlabs/sui", package = "sui-sdk" } +sui-types = { git = "https://github.com/mystenlabs/sui", package = "sui-types" } +sui-json-rpc-types = { git = "https://github.com/mystenlabs/sui", package = "sui-json-rpc-types" } +sui-keys = { git = "https://github.com/mystenlabs/sui", package = "sui-keys" } +shared-crypto = { git = "https://github.com/mystenlabs/sui", package = "shared-crypto" } + +# SP1-Sui conversion +sp1-sui = { git = "https://github.com/SoundnessLabs/sp1-sui" } +sp1-sdk = { workspace = true } + +# Serialization +bincode = { workspace = true } +serde = { workspace = true } +serde_json = "1.0" +bcs = "0.1" # Binary Canonical Serialization for Sui + +# Error handling +thiserror = { workspace = true } +anyhow = "1.0" + +# Async runtime +tokio = { workspace = true } +async-trait = "0.1" + +# Logging +tracing = { workspace = true } + +# HTTP client for Walrus integration +reqwest = { version = "0.11", features = ["json"] } + +# Utilities +hex = "0.4" +dirs = "5.0" + +# TOML serialization for deployment info +toml = "0.8" diff --git a/crates/client/blockchain/sui/README.md b/crates/client/blockchain/sui/README.md new file mode 100644 index 0000000..c0ccedf --- /dev/null +++ b/crates/client/blockchain/sui/README.md @@ -0,0 +1,65 @@ +# client-sui: Sui Blockchain Integration + +Handles proof submission to Sui blockchain for the Dungeon game. + +## Overview + +This crate provides the integration layer between the game's proof generation (`zk` crate) and Sui blockchain. It handles: + +- **Proof Format Conversion**: SP1 gnark → Sui arkworks +- **Transaction Construction**: Building Sui Move contract calls +- **On-Chain Submission**: Signing and executing transactions + +## Architecture Philosophy + +**Conversion at Client Layer**: The `zk` crate remains blockchain-agnostic. All blockchain-specific logic (including proof format conversion) lives here in `client-sui`. + +**Why?** +- `zk` crate: Pure proof generation, no blockchain dependencies +- `client-sui`: Blockchain integration, conversion, submission +- Proof storage: Consistent format across all backends (RISC0, SP1) + +## Usage + +### Basic Workflow + +```rust +use client_sui::{SuiProofConverter, SuiProofSubmitter}; +use zk::ProofData; + +// 1. Load proof from storage (original SP1 format) +let proof_data: ProofData = load_from_disk()?; + +// 2. Convert to Sui format +let sui_proof = SuiProofConverter::convert(proof_data)?; + +// 3. Submit to Sui +let submitter = SuiProofSubmitter::new(sui_client).await?; +let tx_digest = submitter.submit_proof(vk_object_id, proof_data).await?; +``` + +### Verifying Key Deployment + +```rust +// One-time setup: Deploy VK to Sui +let vk_bytes = sui_proof.verifying_key; +let vk_object_id = submitter + .deploy_verifying_key(vk_bytes, 1) + .await?; +``` + +## Modules + +- `converter`: SP1 → Sui proof format conversion +- `submitter`: Sui transaction construction and submission + +## Dependencies + +- `sp1-sui`: gnark → arkworks conversion utility +- `sui-sdk`: Sui blockchain client +- `zk`: Game proof data structures + +## See Also + +- [SP1-Sui Integration Guide](../../../docs/SP1_SUI_INTEGRATION.md) +- [Move Contract: proof_verifier.move](../../../contracts/move/sources/proof_verifier.move) diff --git a/crates/client/blockchain/sui/src/client.rs b/crates/client/blockchain/sui/src/client.rs new file mode 100644 index 0000000..3519642 --- /dev/null +++ b/crates/client/blockchain/sui/src/client.rs @@ -0,0 +1,364 @@ +//! Sui blockchain client implementation. + +use std::sync::Arc; + +use anyhow::{Context, Result, anyhow}; +use sui_keys::keystore::{AccountKeystore, FileBasedKeystore}; +use sui_sdk::{SuiClient, SuiClientBuilder}; +use sui_types::base_types::SuiAddress; +use sui_types::crypto::SuiKeyPair; + +use crate::config::deployment::DeploymentInfo; +use crate::config::network::SuiConfig; +use crate::contracts::GameSessionContract; + +/// Sui blockchain client. +/// +/// Provides unified access to all Sui blockchain operations for the game. +pub struct SuiBlockchainClient { + /// Configuration + pub config: SuiConfig, + + /// Sui RPC client + sui_client: Arc, + + /// Keystore for transaction signing + keystore: FileBasedKeystore, + + /// Active address (signer) + active_address: SuiAddress, + + /// Game session contract client + pub game_session: GameSessionContract, +} + +impl SuiBlockchainClient { + /// Create a new Sui blockchain client. + /// + /// # Arguments + /// + /// * `config` - Sui configuration (network, package ID, etc.) + /// + /// # Returns + /// + /// Configured client ready to interact with Sui network. + /// + /// # Errors + /// + /// Returns error if configuration is invalid or Sui SDK initialization fails. + pub async fn new(config: SuiConfig) -> Result { + // Validate configuration + config + .validate() + .map_err(|e| anyhow!("Invalid configuration: {}", e))?; + + tracing::info!( + "Initializing Sui client for network: {}", + config.network_name() + ); + + // Initialize Sui SDK client + let sui_client = Arc::new( + SuiClientBuilder::default() + .build(config.get_rpc_url()) + .await + .context("Failed to connect to Sui RPC")?, + ); + + tracing::debug!("Connected to Sui RPC: {}", config.get_rpc_url()); + + // Load keystore from default Sui CLI location (~/.sui/sui_config/sui.keystore) + let keystore_path = sui_config_dir()?.join(SUI_KEYSTORE_FILENAME); + + tracing::debug!("Keystore path: {}", keystore_path.display()); + + // Load keystore (or create empty if missing) + let keystore = FileBasedKeystore::load_or_create(&keystore_path).context(format!( + "Failed to access keystore at {}", + keystore_path.display() + ))?; + + // Fail if keystore is empty - we don't auto-generate keys + if keystore.addresses().is_empty() { + return Err(anyhow!( + "No addresses found in keystore at {}. \ + Generate a key first with 'sui client new-address ed25519' or 'cargo xtask sui keygen'.", + keystore_path.display() + )); + } + + // Get active address (from alias or first address) + let active_address = if let Ok(alias) = std::env::var("SUI_ACTIVE_ALIAS") { + // Use address by alias + *keystore + .addresses_with_alias() + .iter() + .find(|(_, a)| a.alias == alias) + .ok_or_else(|| anyhow!("Address with alias '{}' not found in keystore", alias))? + .0 + } else { + // Use first address as default + keystore + .addresses() + .first() + .copied() + .ok_or_else(|| anyhow!( + "No addresses found in keystore. Generate a key first with 'cargo xtask sui keygen'." + ))? + }; + + tracing::info!("Using address: {}", active_address); + + // Get package ID from config + let package_id = config.package_id.clone().ok_or_else(|| { + anyhow!("Package ID not configured. Run 'cargo xtask sui deploy' first.") + })?; + + // Load VK from deployment info if available + let _network = match config.network { + crate::config::SuiNetwork::Mainnet => "mainnet", + crate::config::SuiNetwork::Testnet => "testnet", + crate::config::SuiNetwork::Local => "local", + }; + + let vk_object_id = DeploymentInfo::from_env().ok().and_then(|d| d.vk_object_id); + + if let Some(ref vk_id) = vk_object_id { + tracing::info!("Loaded VK object ID from deployment: {}", vk_id); + } else { + tracing::warn!( + "VK object ID not found in deployment info. \ + Proof verification will fail until VK is configured. \ + Run 'cargo xtask sui setup' to register VK." + ); + } + + // Create game session contract client + let game_session = GameSessionContract::new(package_id, vk_object_id); + + Ok(Self { + config, + sui_client, + keystore, + active_address, + game_session, + }) + } + + /// Create client with default configuration (testnet). + pub async fn new_with_defaults() -> Result { + Self::new(SuiConfig::default()).await + } + + /// Set verifying key object ID. + /// + /// This should be called after deploying the VK to the network. + pub fn set_verifying_key(&mut self, vk_id: String) { + self.game_session.set_vk(vk_id); + } + + /// Get network name. + pub fn network(&self) -> &str { + match self.config.network { + crate::config::SuiNetwork::Mainnet => "mainnet", + crate::config::SuiNetwork::Testnet => "testnet", + crate::config::SuiNetwork::Local => "local", + } + } + + /// Get active Sui address. + pub fn active_address(&self) -> SuiAddress { + self.active_address + } + + /// Get Sui client reference. + pub fn sui_client(&self) -> &SuiClient { + &self.sui_client + } + + /// Get keypair for signing transactions. + #[allow(dead_code)] + fn get_key_pair(&self) -> Result<&SuiKeyPair> { + self.keystore + .export(&self.active_address) + .context("Failed to get keypair for active address") + } + + // ======================================================================== + // Convenience Wrappers (Delegate to GameSessionContract with DI) + // ======================================================================== + + /// Create a new game session on-chain. + /// + /// Convenience wrapper that injects SDK dependencies into GameSessionContract. + /// + /// # Arguments + /// + /// * `oracle_root` - Content hash of oracle data + /// * `initial_state_root` - Initial game state root + /// * `seed_commitment` - RNG seed commitment + /// + /// # Returns + /// + /// SessionId of the created on-chain object. + pub async fn create_session( + &self, + oracle_root: [u8; 32], + initial_state_root: [u8; 32], + seed_commitment: [u8; 32], + ) -> Result { + self.game_session + .create( + &self.sui_client, + &self.keystore, + self.active_address, + self.config.gas_budget, + oracle_root, + initial_state_root, + seed_commitment, + ) + .await + } + + /// Update session with ZK proof. + /// + /// Convenience wrapper that injects SDK dependencies into GameSessionContract. + /// + /// # Arguments + /// + /// * `session_id` - Session object ID to update + /// * `proof` - Proof submission containing ZK proof and journal + /// + /// # Returns + /// + /// Transaction digest of the update transaction. + pub async fn update_session( + &self, + session_id: &crate::core::SessionId, + proof: crate::core::ProofSubmission, + blob_object_id: &str, + ) -> Result { + self.game_session + .update( + &self.sui_client, + &self.keystore, + self.active_address, + self.config.gas_budget, + session_id, + proof, + blob_object_id, + ) + .await + } + + /// Update session state with ZK proof without Walrus blob (testing only). + /// + /// Convenience wrapper that injects SDK dependencies into GameSessionContract. + /// This bypasses Walrus blob upload and directly calls `update_without_blob`. + /// + /// # Arguments + /// + /// * `session_id` - Session object ID to update + /// * `proof` - Proof submission data (proof, journal_digest, actions_root, state_root, nonce) + /// + /// # Returns + /// + /// Transaction digest of the update transaction. + pub async fn update_session_without_blob( + &self, + session_id: &crate::core::SessionId, + proof: crate::core::ProofSubmission, + ) -> Result { + self.game_session + .update_without_blob( + &self.sui_client, + &self.keystore, + self.active_address, + self.config.gas_budget, + session_id, + proof, + ) + .await + } + + /// Finalize a game session. + /// + /// Convenience wrapper that injects SDK dependencies into GameSessionContract. + /// + /// # Arguments + /// + /// * `session_id` - Session object ID to finalize + /// + /// # Returns + /// + /// Transaction digest of the finalize transaction. + pub async fn finalize_session( + &self, + session_id: &crate::core::SessionId, + ) -> Result { + self.game_session + .finalize( + &self.sui_client, + &self.keystore, + self.active_address, + self.config.gas_budget, + session_id, + ) + .await + } + + /// Get session state from blockchain. + /// + /// Convenience wrapper that injects SDK dependencies into GameSessionContract. + /// + /// # Arguments + /// + /// * `session_id` - Session object ID to query + /// + /// # Returns + /// + /// GameSession struct with all fields from on-chain data. + pub async fn get_session( + &self, + session_id: &crate::core::SessionId, + ) -> Result { + self.game_session.get(&self.sui_client, session_id).await + } + + /// Get current state root for a session. + pub async fn get_state_root( + &self, + session_id: &crate::core::SessionId, + ) -> Result { + self.game_session + .get_state_root(&self.sui_client, session_id) + .await + } + + /// Get current nonce for a session. + pub async fn get_nonce(&self, session_id: &crate::core::SessionId) -> Result { + self.game_session + .get_nonce(&self.sui_client, session_id) + .await + } + + /// Check if session is active (not finalized). + pub async fn is_session_active(&self, session_id: &crate::core::SessionId) -> Result { + self.game_session + .is_active(&self.sui_client, session_id) + .await + } +} + +// ============================================================================ +// Helper Functions +// ============================================================================ + +/// Default Sui keystore filename +const SUI_KEYSTORE_FILENAME: &str = "sui.keystore"; + +/// Get Sui config directory (~/.sui/sui_config/) +fn sui_config_dir() -> Result { + let home = dirs::home_dir().ok_or_else(|| anyhow!("Could not determine home directory"))?; + Ok(home.join(".sui").join("sui_config")) +} diff --git a/crates/client/blockchain/sui/src/config/deployment.rs b/crates/client/blockchain/sui/src/config/deployment.rs new file mode 100644 index 0000000..564c658 --- /dev/null +++ b/crates/client/blockchain/sui/src/config/deployment.rs @@ -0,0 +1,150 @@ +//! Deployment information management. +//! +//! Deployment information is now stored in .env file using environment variables: +//! - SUI_NETWORK - Network name (testnet, mainnet, local) +//! - SUI_PACKAGE_ID - Deployed package ID +//! - SUI_VK_OBJECT_ID - Verifying key object ID +//! - SUI_SESSION_OBJECT_ID - Game session object ID + +use std::env; +use std::fs::{self, OpenOptions}; +use std::io::Write; +use std::path::PathBuf; + +use anyhow::{Context, Result}; + +/// Sui deployment information. +/// +/// Stores deployment artifacts and metadata. +/// This is now read from and written to .env file. +#[derive(Debug, Clone)] +pub struct DeploymentInfo { + /// Network name (e.g., "testnet", "mainnet", "local") + pub network: String, + + /// Deployed package ID (Move package) + pub package_id: String, + + /// Verifying key object ID (on-chain VK for proof verification) + pub vk_object_id: Option, + + /// Game session object ID (for current active session) + pub session_object_id: Option, +} + +impl DeploymentInfo { + /// Create new deployment info. + pub fn new(network: String, package_id: String) -> Self { + Self { + network, + package_id, + vk_object_id: None, + session_object_id: None, + } + } + + /// Load deployment info from environment variables. + /// + /// Environment variables: + /// - SUI_NETWORK - Network name (required) + /// - SUI_PACKAGE_ID - Package ID (required) + /// - SUI_VK_OBJECT_ID - VK object ID (optional) + /// - SUI_SESSION_OBJECT_ID - Session object ID (optional) + pub fn from_env() -> Result { + let network = + env::var("SUI_NETWORK").context("SUI_NETWORK environment variable not set")?; + + let package_id = + env::var("SUI_PACKAGE_ID").context("SUI_PACKAGE_ID environment variable not set")?; + + let vk_object_id = env::var("SUI_VK_OBJECT_ID").ok(); + let session_object_id = env::var("SUI_SESSION_OBJECT_ID").ok(); + + Ok(Self { + network, + package_id, + vk_object_id, + session_object_id, + }) + } + + /// Update VK object ID. + pub fn set_vk_object_id(&mut self, vk_object_id: String) { + self.vk_object_id = Some(vk_object_id); + } + + /// Update session object ID. + pub fn set_session_object_id(&mut self, session_object_id: String) { + self.session_object_id = Some(session_object_id); + } + + /// Save deployment info to .env file. + /// + /// Appends or updates environment variables in .env file. + pub fn save_to_env(&self) -> Result<()> { + let env_path = PathBuf::from(".env"); + + // Read existing .env content if it exists + let existing_content = if env_path.exists() { + fs::read_to_string(&env_path).context("Failed to read existing .env file")? + } else { + String::new() + }; + + // Parse existing variables + let mut env_vars: Vec<(String, String)> = existing_content + .lines() + .filter(|line| !line.trim().is_empty() && !line.trim().starts_with('#')) + .filter_map(|line| { + let parts: Vec<&str> = line.splitn(2, '=').collect(); + if parts.len() == 2 { + Some((parts[0].trim().to_string(), parts[1].trim().to_string())) + } else { + None + } + }) + .collect(); + + // Update or add SUI_* variables + Self::upsert_var(&mut env_vars, "SUI_NETWORK", &self.network); + Self::upsert_var(&mut env_vars, "SUI_PACKAGE_ID", &self.package_id); + + if let Some(ref vk_id) = self.vk_object_id { + Self::upsert_var(&mut env_vars, "SUI_VK_OBJECT_ID", vk_id); + } + + if let Some(ref session_id) = self.session_object_id { + Self::upsert_var(&mut env_vars, "SUI_SESSION_OBJECT_ID", session_id); + } + + // Write back to .env file + let mut file = OpenOptions::new() + .write(true) + .create(true) + .truncate(true) + .open(&env_path) + .context("Failed to open .env file for writing")?; + + // Write comments if file is new + if existing_content.is_empty() { + writeln!(file, "# Sui blockchain deployment configuration")?; + writeln!(file)?; + } + + // Write all variables + for (key, value) in env_vars { + writeln!(file, "{}={}", key, value)?; + } + + Ok(()) + } + + /// Helper to upsert a variable in the env_vars list. + fn upsert_var(vars: &mut Vec<(String, String)>, key: &str, value: &str) { + if let Some(pos) = vars.iter().position(|(k, _)| k == key) { + vars[pos] = (key.to_string(), value.to_string()); + } else { + vars.push((key.to_string(), value.to_string())); + } + } +} diff --git a/crates/client/blockchain/sui/src/config/mod.rs b/crates/client/blockchain/sui/src/config/mod.rs new file mode 100644 index 0000000..6a95969 --- /dev/null +++ b/crates/client/blockchain/sui/src/config/mod.rs @@ -0,0 +1,8 @@ +//! Sui blockchain configuration and deployment. + +pub mod deployment; +pub mod network; + +// Re-export commonly used items +pub use deployment::DeploymentInfo; +pub use network::{SuiConfig, SuiNetwork}; diff --git a/crates/client/blockchain/sui/src/config/network.rs b/crates/client/blockchain/sui/src/config/network.rs new file mode 100644 index 0000000..044e385 --- /dev/null +++ b/crates/client/blockchain/sui/src/config/network.rs @@ -0,0 +1,160 @@ +//! Sui blockchain configuration. + +use std::env; + +/// Sui network types. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum SuiNetwork { + /// Sui mainnet + Mainnet, + /// Sui testnet + Testnet, + /// Local Sui network + Local, +} + +impl SuiNetwork { + pub fn default_rpc_url(&self) -> &str { + match self { + SuiNetwork::Mainnet => "https://fullnode.mainnet.sui.io:443", + SuiNetwork::Testnet => "https://fullnode.testnet.sui.io:443", + SuiNetwork::Local => "http://127.0.0.1:9000", + } + } +} + +/// Sui-specific blockchain infrastructure configuration. +/// +/// This contains only infrastructure-level settings (network, RPC, gas). +/// Game domain configuration (VK, seed commitment) is managed separately +/// via on-chain session objects (OnChainGameSession). +pub struct SuiConfig { + /// Sui network to connect to + pub network: SuiNetwork, + + /// Custom RPC endpoint URL (overrides network default) + pub rpc_url: Option, + + /// Package ID of the deployed game contract + pub package_id: Option, + + /// Gas budget for transactions (in MIST) + pub gas_budget: u64, +} + +impl SuiConfig { + /// Create a new Sui configuration. + pub fn new(network: SuiNetwork) -> Self { + Self { + network, + rpc_url: None, + package_id: None, + gas_budget: 100_000_000, // 0.1 SUI + } + } + + /// Load configuration from environment variables. + /// + /// Environment variables: + /// - `SUI_NETWORK` - Network name (mainnet, testnet, local) (default: testnet) + /// - `SUI_RPC_URL` - Custom RPC endpoint URL (optional) + /// - `SUI_PACKAGE_ID` - Deployed game package ID (optional) + /// - `SUI_VK_OBJECT_ID` - Verifying key object ID (optional) + /// - `SUI_SESSION_OBJECT_ID` - Game session object ID (optional) + /// - `SUI_GAS_BUDGET` - Gas budget in MIST (default: 100000000) + pub fn from_env() -> Result { + let network = match env::var("SUI_NETWORK") + .unwrap_or_else(|_| "testnet".to_string()) + .to_lowercase() + .as_str() + { + "mainnet" => SuiNetwork::Mainnet, + "testnet" => SuiNetwork::Testnet, + "local" => SuiNetwork::Local, + other => { + return Err(format!( + "Invalid SUI_NETWORK: {}. Must be mainnet, testnet, or local", + other + )); + } + }; + + let rpc_url = env::var("SUI_RPC_URL").ok(); + let package_id = env::var("SUI_PACKAGE_ID").ok(); + + let gas_budget = env::var("SUI_GAS_BUDGET") + .ok() + .and_then(|s| s.parse::().ok()) + .unwrap_or(100_000_000); + + Ok(Self { + network, + rpc_url, + package_id, + gas_budget, + }) + } + + /// Set custom RPC URL. + pub fn with_rpc_url(mut self, url: String) -> Self { + self.rpc_url = Some(url); + self + } + + /// Set package ID. + pub fn with_package_id(mut self, package_id: String) -> Self { + self.package_id = Some(package_id); + self + } + + /// Set gas budget. + pub fn with_gas_budget(mut self, budget: u64) -> Self { + self.gas_budget = budget; + self + } + + /// Get the RPC URL (custom or default for network). + pub fn get_rpc_url(&self) -> &str { + self.rpc_url + .as_deref() + .unwrap_or_else(|| self.network.default_rpc_url()) + } + + /// Validate configuration. + pub fn validate(&self) -> Result<(), String> { + // Validate RPC URL format + let url = self.get_rpc_url(); + if !url.starts_with("http://") && !url.starts_with("https://") { + return Err(format!("Invalid RPC URL format: {}", url)); + } + + // Validate gas budget + if self.gas_budget == 0 { + return Err("Gas budget must be greater than 0".to_string()); + } + + // Package ID is optional (may not be deployed yet) + if let Some(ref pkg_id) = self.package_id + && pkg_id.is_empty() + { + return Err("Package ID cannot be empty".to_string()); + } + + Ok(()) + } + + /// Get network name. + pub fn network_name(&self) -> &str { + match self.network { + SuiNetwork::Mainnet => "sui-mainnet", + SuiNetwork::Testnet => "sui-testnet", + SuiNetwork::Local => "sui-local", + } + } +} + +impl Default for SuiConfig { + fn default() -> Self { + Self::new(SuiNetwork::Testnet) + } +} diff --git a/crates/client/blockchain/sui/src/contracts/game_session.rs b/crates/client/blockchain/sui/src/contracts/game_session.rs new file mode 100644 index 0000000..018cefb --- /dev/null +++ b/crates/client/blockchain/sui/src/contracts/game_session.rs @@ -0,0 +1,1093 @@ +//! game_session Move contract integration. +//! +//! This module provides direct interaction with the on-chain `game_session` contract. +//! +//! ## Move Contract Reference +//! +//! ```move +//! module dungeon::game_session { +//! public struct GameSession has key, store { +//! id: UID, +//! player: address, +//! oracle_root: vector, +//! initial_state_root: vector, +//! seed_commitment: vector, +//! state_root: vector, +//! nonce: u64, +//! pending_action_logs: u64, +//! finalized: bool, +//! } +//! +//! public fun create(...): GameSession; +//! public fun update(session: &mut GameSession, ...); +//! public fun finalize(session: &mut GameSession, ...); +//! } +//! ``` + +use anyhow::{Context, Result, anyhow}; +use serde::{Deserialize, Serialize}; +use shared_crypto::intent::{Intent, IntentMessage}; +use sui_keys::keystore::{AccountKeystore, FileBasedKeystore}; +use sui_sdk::SuiClient; +use sui_sdk::rpc_types::{SuiObjectDataOptions, SuiTransactionBlockEffectsAPI}; +use sui_types::Identifier; +use sui_types::base_types::{ObjectID, SuiAddress}; +use sui_types::object::Owner; +use sui_types::programmable_transaction_builder::ProgrammableTransactionBuilder; +use sui_types::transaction::{ObjectArg, TransactionData}; + +use crate::core::types::{ProofSubmission, SessionId, StateRoot, TxDigest}; + +// ============================================================================ +// GameSession Object (1:1 mapping with Move struct) +// ============================================================================ + +/// On-chain GameSession object. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct GameSession { + /// Session Object ID + pub id: String, + + /// Player address (session owner) + pub player: Vec, + + /// Oracle data commitment (content hash) + pub oracle_root: [u8; 32], + + /// Initial state root at game start + pub initial_state_root: [u8; 32], + + /// Seed commitment for RNG fairness + pub seed_commitment: [u8; 32], + + /// Current game state root + pub state_root: [u8; 32], + + /// Action execution nonce + pub nonce: u64, + + /// Number of pending action logs + pub pending_action_logs: u64, + + /// Whether the session is finalized + pub finalized: bool, +} + +impl GameSession { + pub fn new( + id: String, + player: Vec, + oracle_root: [u8; 32], + initial_state_root: [u8; 32], + seed_commitment: [u8; 32], + ) -> Self { + Self { + id, + player, + oracle_root, + initial_state_root, + seed_commitment, + state_root: initial_state_root, + nonce: 0, + pending_action_logs: 0, + finalized: false, + } + } + + pub fn is_finalized(&self) -> bool { + self.finalized + } +} + +// ============================================================================ +// GameSessionContract - Contract metadata and transaction builders +// ============================================================================ + +/// Game session contract metadata and transaction builders. +/// +/// This struct contains only contract configuration (package ID, VK ID). +/// All blockchain interactions use Dependency Injection pattern - SDK resources +/// (SuiClient, keystore, address) are passed as method arguments. +/// +/// ## Design Pattern: Dependency Injection +/// +/// Benefits: +/// - Clear separation: Contract = domain logic, Client = infrastructure +/// - Testability: Can test contract methods independently with mocks +/// - Reusability: Contract can be used in different contexts +/// - Scalability: Adding new contracts doesn't bloat the client +pub struct GameSessionContract { + /// Sui package ID (dungeon::game_session module) + pub package_id: String, + + /// Verifying key object ID (for proof verification) + pub vk_object_id: Option, +} + +impl GameSessionContract { + /// Create new game session contract client. + pub fn new(package_id: String, vk_object_id: Option) -> Self { + Self { + package_id, + vk_object_id, + } + } + + /// Set verifying key object ID. + pub fn set_vk(&mut self, vk_id: String) { + self.vk_object_id = Some(vk_id); + } + + /// Get package ID as ObjectID. + fn package_object_id(&self) -> Result { + self.package_id.parse().context("Invalid package ID format") + } + + /// Get gas coin for transaction payment. + /// + /// Fetches the first available gas coin for the given address. + async fn get_gas_coin( + sui_client: &SuiClient, + active_address: SuiAddress, + ) -> Result { + let gas_coins = sui_client + .coin_read_api() + .get_coins(active_address, None, None, None) + .await + .context("Failed to get gas coins")?; + + let gas_coin = gas_coins + .data + .first() + .ok_or_else(|| anyhow!("No gas coins available for address {}", active_address))?; + + tracing::debug!( + "Using gas coin: {} with balance: {}", + gas_coin.coin_object_id, + gas_coin.balance + ); + + Ok(gas_coin.object_ref()) + } + + /// Create a new game session on-chain. + /// + /// Builds and executes a PTB calling `dungeon::game_session::create()`. + /// + /// # Arguments + /// + /// * `sui_client` - Sui RPC client (injected dependency) + /// * `keystore` - Keystore for transaction signing (injected dependency) + /// * `active_address` - Signer address (injected dependency) + /// * `gas_budget` - Gas budget in MIST + /// * `oracle_root` - Content hash of oracle data + /// * `initial_state_root` - Initial game state root + /// * `seed_commitment` - RNG seed commitment + /// + /// # Returns + /// + /// SessionId of the created on-chain object. + /// + /// # Errors + /// + /// Returns error if: + /// - PTB construction fails + /// - Transaction execution fails + /// - Created object cannot be parsed from response + #[allow(clippy::too_many_arguments)] // SDK dependency injection pattern + pub async fn create( + &self, + sui_client: &SuiClient, + keystore: &FileBasedKeystore, + active_address: SuiAddress, + gas_budget: u64, + oracle_root: [u8; 32], + initial_state_root: [u8; 32], + seed_commitment: [u8; 32], + ) -> Result { + tracing::info!("Creating game session on-chain..."); + + // Build Programmable Transaction Block + let mut ptb = ProgrammableTransactionBuilder::new(); + + // Prepare pure arguments (vectors of bytes) + let oracle_root_arg = ptb.pure(oracle_root.to_vec())?; + let initial_state_root_arg = ptb.pure(initial_state_root.to_vec())?; + let seed_commitment_arg = ptb.pure(seed_commitment.to_vec())?; + + // Add Move call: package::game_session::create + let package_id = self.package_object_id()?; + ptb.programmable_move_call( + package_id, + Identifier::new("game_session")?, + Identifier::new("create")?, + vec![], // No type arguments + vec![oracle_root_arg, initial_state_root_arg, seed_commitment_arg], + ); + + // Finalize PTB + let pt = ptb.finish(); + + // Get current gas price + let gas_price = sui_client + .read_api() + .get_reference_gas_price() + .await + .context("Failed to get reference gas price")?; + + // Get gas coin for payment + let gas_coin = Self::get_gas_coin(sui_client, active_address).await?; + + // Build transaction data + let tx_data = TransactionData::new_programmable( + active_address, + vec![gas_coin], + pt, + gas_budget, + gas_price, + ); + + // Sign transaction with intent + let keypair = keystore + .export(&active_address) + .context("Failed to export keypair from keystore")?; + + let signature = sui_types::crypto::Signature::new_secure( + &IntentMessage::new(Intent::sui_transaction(), &tx_data), + keypair, + ); + + // Execute transaction + tracing::debug!("Executing create session transaction..."); + let response = sui_client + .quorum_driver_api() + .execute_transaction_block( + sui_types::transaction::Transaction::from_data(tx_data, vec![signature]), + sui_sdk::rpc_types::SuiTransactionBlockResponseOptions::new() + .with_effects() + .with_object_changes(), + None, // No execution options + ) + .await + .context("Failed to execute create session transaction")?; + + // Extract created object ID from response + let object_changes = response + .object_changes + .ok_or_else(|| anyhow!("No object changes in transaction response"))?; + + for change in object_changes { + if let sui_sdk::rpc_types::ObjectChange::Created { + object_id, + object_type, + .. + } = change + { + // Verify it's a GameSession object + if object_type + .to_string() + .contains("game_session::GameSession") + { + let session_id = SessionId::new(object_id.to_string()); + tracing::info!("✓ Session created: {}", session_id.as_str()); + return Ok(session_id); + } + } + } + + Err(anyhow!( + "Failed to find created GameSession object in transaction response" + )) + } + + /// Update session with verified proof and pre-uploaded Walrus blob. + /// + /// Builds and executes a PTB calling `dungeon::game_session::update()`. + /// + /// **Prerequisites:** + /// - ZK proof must be generated + /// - Action log must be uploaded to Walrus (use WalrusClient separately) + /// - Blob object must be owned by active_address + /// - VK must be registered on-chain + /// + /// This method only handles transaction construction and execution. + /// Walrus upload must be done separately before calling this method. + /// + /// # Arguments + /// + /// * `sui_client` - Sui RPC client (injected dependency) + /// * `keystore` - Keystore for transaction signing (injected dependency) + /// * `active_address` - Signer address (injected dependency) + /// * `gas_budget` - Gas budget in MIST + /// * `session_id` - Session object ID to update + /// * `proof` - Proof submission containing ZK proof and journal + /// * `blob_object_id` - Sui ObjectID of the Walrus Blob (NOT Walrus blob_id!) + /// + /// # Returns + /// + /// Transaction digest of the update transaction. + /// + /// # Errors + /// + /// Returns error if: + /// - VK object ID is not configured + /// - Session/VK/Blob objects cannot be fetched + /// - Blob object is not owned by active_address + /// - PTB construction fails + /// - Transaction execution fails + #[allow(clippy::too_many_arguments)] // SDK dependency injection pattern + pub async fn update( + &self, + sui_client: &SuiClient, + keystore: &FileBasedKeystore, + active_address: SuiAddress, + gas_budget: u64, + session_id: &SessionId, + proof: ProofSubmission, + blob_object_id: &str, + ) -> Result { + tracing::info!( + "Updating session {} with proof (blob: {}...)...", + session_id.as_str(), + &blob_object_id[..blob_object_id.len().min(16)] + ); + + // Verify VK is configured + let vk_id = self.vk_object_id.as_ref().ok_or_else(|| { + anyhow!("Verifying key not configured. Run 'cargo xtask sui setup' first.") + })?; + + // Parse journal to extract new values + let (new_state_root, new_nonce) = proof.parse_journal()?; + + tracing::debug!( + "Proof verification: new_state_root={}, new_nonce={}", + hex::encode(new_state_root), + new_nonce + ); + + // ======================================================================== + // Build Programmable Transaction Block + // ======================================================================== + + let mut ptb = ProgrammableTransactionBuilder::new(); + + // Prepare session object argument (mutable reference) + let session_obj_id: ObjectID = session_id + .as_str() + .parse() + .context("Invalid session ID format")?; + + let session_obj = sui_client + .read_api() + .get_object_with_options(session_obj_id, SuiObjectDataOptions::default()) + .await + .context("Failed to fetch session object")? + .into_object() + .context("Session object not found")?; + + let session_arg = ptb.obj(ObjectArg::ImmOrOwnedObject(session_obj.object_ref()))?; + + // Prepare VK object argument (immutable reference) + let vk_obj_id: ObjectID = vk_id.parse().context("Invalid VK object ID format")?; + + let vk_obj = sui_client + .read_api() + .get_object_with_options(vk_obj_id, SuiObjectDataOptions::default()) + .await + .context("Failed to fetch VK object")? + .into_object() + .context("VK object not found")?; + + let vk_arg = ptb.obj(ObjectArg::ImmOrOwnedObject(vk_obj.object_ref()))?; + + // Prepare Walrus Blob object argument + let blob_obj_id: ObjectID = blob_object_id + .parse() + .context("Invalid Walrus blob object ID format")?; + + let blob_obj = sui_client + .read_api() + .get_object_with_options(blob_obj_id, SuiObjectDataOptions::default()) + .await + .context("Failed to fetch Walrus blob object")? + .into_object() + .context("Walrus blob object not found")?; + + let blob_arg = ptb.obj(ObjectArg::ImmOrOwnedObject(blob_obj.object_ref()))?; + + // Prepare proof and state arguments + let proof_arg = ptb.pure(proof.proof_points.clone())?; + let new_state_root_arg = ptb.pure(new_state_root.to_vec())?; + let new_nonce_arg = ptb.pure(new_nonce)?; + + // ======================================================================== + // Call game_session::update + // ======================================================================== + + let package_id = self.package_object_id()?; + ptb.programmable_move_call( + package_id, + Identifier::new("game_session")?, + Identifier::new("update")?, + vec![], // No type arguments + vec![ + session_arg, + vk_arg, + proof_arg, + new_state_root_arg, + new_nonce_arg, + blob_arg, // Walrus Blob object + ], + ); + + // Finalize PTB + let pt = ptb.finish(); + + // ======================================================================== + // Execute transaction + // ======================================================================== + + // Get current gas price + let gas_price = sui_client + .read_api() + .get_reference_gas_price() + .await + .context("Failed to get reference gas price")?; + + // Get gas coin for payment + let gas_coin = Self::get_gas_coin(sui_client, active_address).await?; + + // Build transaction data + let tx_data = TransactionData::new_programmable( + active_address, + vec![gas_coin], + pt, + gas_budget, + gas_price, + ); + + // Sign transaction with intent + let keypair = keystore + .export(&active_address) + .context("Failed to export keypair from keystore")?; + + let signature = sui_types::crypto::Signature::new_secure( + &IntentMessage::new(Intent::sui_transaction(), &tx_data), + keypair, + ); + + // Execute transaction + tracing::debug!("Executing update session transaction..."); + let response = sui_client + .quorum_driver_api() + .execute_transaction_block( + sui_types::transaction::Transaction::from_data(tx_data, vec![signature]), + sui_sdk::rpc_types::SuiTransactionBlockResponseOptions::new().with_effects(), + None, // No execution options + ) + .await + .context("Failed to execute update session transaction")?; + + let digest = TxDigest::new(response.digest.to_string()); + tracing::info!("✓ Session updated. Transaction: {}", digest.as_str()); + + Ok(digest) + } + + /// Update session state without Walrus blob (testing only). + /// + /// Similar to `update()` but calls `update_without_blob()` which bypasses Walrus blob + /// requirement. The actions_root is provided directly instead of being derived from blob_id. + /// + /// # Arguments + /// + /// * `sui_client` - Sui RPC client (injected dependency) + /// * `keystore` - Keystore for transaction signing (injected dependency) + /// * `active_address` - Signer address (injected dependency) + /// * `gas_budget` - Gas budget in MIST + /// * `session_id` - Session object ID to update + /// * `proof` - Proof submission containing ZK proof and journal + /// + /// # Returns + /// + /// Transaction digest of the update transaction. + pub async fn update_without_blob( + &self, + sui_client: &SuiClient, + keystore: &FileBasedKeystore, + active_address: SuiAddress, + gas_budget: u64, + session_id: &SessionId, + proof: ProofSubmission, + ) -> Result { + tracing::info!( + "[TEST] Updating session {} with proof (without blob)...", + session_id.as_str() + ); + + // Verify VK is configured + let vk_id = self.vk_object_id.as_ref().ok_or_else(|| { + anyhow!("Verifying key not configured. Run 'cargo xtask sui setup' first.") + })?; + + // Parse journal to extract values + let journal_fields = zk::parse_journal(&proof.journal) + .map_err(|e| anyhow!("Failed to parse journal: {}", e))?; + + let new_state_root = journal_fields.new_state_root; + let new_nonce = journal_fields.new_nonce; + let actions_root = journal_fields.actions_root; + + tracing::debug!( + "[TEST] Proof verification: new_state_root={}, new_nonce={}, actions_root={}", + hex::encode(new_state_root), + new_nonce, + hex::encode(actions_root) + ); + + // ======================================================================== + // Build Programmable Transaction Block + // ======================================================================== + + let mut ptb = ProgrammableTransactionBuilder::new(); + + // Prepare session object argument (mutable reference) + let session_obj_id: ObjectID = session_id + .as_str() + .parse() + .context("Invalid session ID format")?; + + let session_obj = sui_client + .read_api() + .get_object_with_options( + session_obj_id, + SuiObjectDataOptions::new() + .with_type() + .with_owner() + .with_previous_transaction(), + ) + .await + .context("Failed to fetch session object")? + .into_object() + .context("Session object not found")?; + + tracing::debug!( + "[TEST] Session object: id={}, version={}, digest={:?}, owner={:?}", + session_obj.object_id, + session_obj.version, + session_obj.digest, + session_obj.owner + ); + + let session_arg = ptb.obj(ObjectArg::ImmOrOwnedObject(session_obj.object_ref()))?; + + // Prepare VK object argument (immutable reference) + let vk_obj_id: ObjectID = vk_id.parse().context("Invalid VK object ID format")?; + + let vk_obj = sui_client + .read_api() + .get_object_with_options( + vk_obj_id, + SuiObjectDataOptions::new() + .with_type() + .with_owner() + .with_previous_transaction(), + ) + .await + .context("Failed to fetch VK object")? + .into_object() + .context("VK object not found")?; + + tracing::debug!( + "[TEST] VK object: id={}, version={}, digest={:?}, owner={:?}", + vk_obj.object_id, + vk_obj.version, + vk_obj.digest, + vk_obj.owner + ); + + // VK is a shared object, not owned + let vk_arg = if let Some(Owner::Shared { + initial_shared_version, + }) = &vk_obj.owner + { + tracing::debug!( + "[TEST] VK is shared object with initial version: {}", + initial_shared_version.value() + ); + // For shared objects, we need to use CallArg directly + ptb.input(sui_types::transaction::CallArg::Object( + ObjectArg::SharedObject { + id: vk_obj.object_id, + initial_shared_version: *initial_shared_version, + mutability: sui_types::transaction::SharedObjectMutability::Immutable, + }, + ))? + } else { + // Fallback to ImmOrOwnedObject if not shared (this shouldn't happen for VK) + tracing::warn!("[TEST] VK is not a shared object, using as owned/immutable"); + ptb.input(sui_types::transaction::CallArg::Object( + ObjectArg::ImmOrOwnedObject(vk_obj.object_ref()), + ))? + }; + + // Prepare proof and state arguments + let proof_arg = ptb.pure(proof.proof_points.clone())?; + let journal_digest_arg = ptb.pure(proof.journal_digest.to_vec())?; + let actions_root_arg = ptb.pure(actions_root.to_vec())?; + let new_state_root_arg = ptb.pure(new_state_root.to_vec())?; + let new_nonce_arg = ptb.pure(new_nonce)?; + + tracing::debug!( + "[TEST] Proof data: proof_points_len={}, journal_digest={}, actions_root={}, new_state_root={}, new_nonce={}", + proof.proof_points.len(), + hex::encode(proof.journal_digest), + hex::encode(actions_root), + hex::encode(new_state_root), + new_nonce + ); + + // ======================================================================== + // Call game_session::update_without_blob + // ======================================================================== + + let package_id = self.package_object_id()?; + ptb.programmable_move_call( + package_id, + Identifier::new("game_session")?, + Identifier::new("update_without_blob")?, + vec![], // No type arguments + vec![ + session_arg, + vk_arg, + proof_arg, + journal_digest_arg, + actions_root_arg, + new_state_root_arg, + new_nonce_arg, + ], + ); + + // Finalize PTB + let pt = ptb.finish(); + + // ======================================================================== + // Execute transaction + // ======================================================================== + + // Get current gas price + let gas_price = sui_client + .read_api() + .get_reference_gas_price() + .await + .context("Failed to get reference gas price")?; + + // Get gas coin for payment + let gas_coin = Self::get_gas_coin(sui_client, active_address).await?; + + // Build transaction data + let tx_data = TransactionData::new_programmable( + active_address, + vec![gas_coin], + pt, + gas_budget, + gas_price, + ); + + // Sign transaction with intent + let keypair = keystore + .export(&active_address) + .context("Failed to export keypair from keystore")?; + + let signature = sui_types::crypto::Signature::new_secure( + &IntentMessage::new(Intent::sui_transaction(), &tx_data), + keypair, + ); + + // Dry run first to check for errors + tracing::debug!("[TEST] Performing dry-run of update session transaction..."); + let dry_run_result = sui_client + .read_api() + .dry_run_transaction_block(tx_data.clone()) + .await; + + match dry_run_result { + Ok(dry_run) => { + tracing::debug!("[TEST] Dry-run status: {:?}", dry_run.effects.status()); + if let sui_sdk::rpc_types::SuiExecutionStatus::Failure { error } = + dry_run.effects.status() + { + tracing::error!("[TEST] Dry-run FAILED: {}", error); + return Err(anyhow!("Dry-run failed: {}", error)); + } + tracing::info!("[TEST] Dry-run successful, proceeding with execution..."); + } + Err(e) => { + tracing::error!("[TEST] Dry-run error: {:?}", e); + return Err(anyhow!("Dry-run error: {}", e)); + } + } + + // Execute transaction + tracing::debug!("[TEST] Executing update session transaction (without blob)..."); + let response = sui_client + .quorum_driver_api() + .execute_transaction_block( + sui_types::transaction::Transaction::from_data(tx_data, vec![signature]), + sui_sdk::rpc_types::SuiTransactionBlockResponseOptions::new() + .with_effects() + .with_events() + .with_object_changes(), + None, // No execution options + ) + .await + .context("Failed to execute update session transaction")?; + + // Check transaction effects for errors + let digest = TxDigest::new(response.digest.to_string()); + + if let Some(effects) = &response.effects { + // Check execution status + let status = &effects.status(); + tracing::debug!("[TEST] Transaction status: {:?}", status); + + match status { + sui_sdk::rpc_types::SuiExecutionStatus::Success => { + tracing::info!( + "✓ [TEST] Session updated (without blob). Transaction: {}", + digest.as_str() + ); + } + sui_sdk::rpc_types::SuiExecutionStatus::Failure { error } => { + tracing::error!( + "[TEST] Transaction FAILED on-chain. Digest: {}, Error: {}", + digest.as_str(), + error + ); + return Err(anyhow!( + "Transaction failed on-chain: {} (tx: {})", + error, + digest.as_str() + )); + } + } + + // Log additional debugging info + if let Some(events) = &response.events { + tracing::debug!( + "[TEST] Transaction events: {} events emitted", + events.data.len() + ); + for event in &events.data { + tracing::debug!("[TEST] Event: {:?}", event.type_); + } + } + + if let Some(obj_changes) = &response.object_changes { + tracing::debug!( + "[TEST] Object changes: {} objects affected", + obj_changes.len() + ); + } + } else { + tracing::warn!("[TEST] No effects returned in transaction response"); + } + + Ok(digest) + } + + /// Finalize a game session. + /// + /// Builds and executes a PTB calling `dungeon::game_session::finalize()`. + /// + /// # Arguments + /// + /// * `sui_client` - Sui RPC client (injected dependency) + /// * `keystore` - Keystore for transaction signing (injected dependency) + /// * `active_address` - Signer address (injected dependency) + /// * `gas_budget` - Gas budget in MIST + /// * `session_id` - Session object ID to finalize + /// + /// # Returns + /// + /// Transaction digest of the finalize transaction. + /// + /// # Errors + /// + /// Returns error if: + /// - Session object cannot be fetched + /// - Session has pending action logs (must be cleaned up first) + /// - PTB construction fails + /// - Transaction execution fails + pub async fn finalize( + &self, + sui_client: &SuiClient, + keystore: &FileBasedKeystore, + active_address: SuiAddress, + gas_budget: u64, + session_id: &SessionId, + ) -> Result { + tracing::info!("Finalizing session {}...", session_id.as_str()); + + // Build Programmable Transaction Block + let mut ptb = ProgrammableTransactionBuilder::new(); + + // Prepare session object argument (mutable reference) + let session_obj_id: ObjectID = session_id + .as_str() + .parse() + .context("Invalid session ID format")?; + + let session_obj = sui_client + .read_api() + .get_object_with_options(session_obj_id, SuiObjectDataOptions::default()) + .await + .context("Failed to fetch session object")? + .into_object() + .context("Session object not found")?; + + let session_arg = ptb.obj(ObjectArg::ImmOrOwnedObject(session_obj.object_ref()))?; + + // Add Move call: package::game_session::finalize + let package_id = self.package_object_id()?; + ptb.programmable_move_call( + package_id, + Identifier::new("game_session")?, + Identifier::new("finalize")?, + vec![], // No type arguments + vec![session_arg], + ); + + // Finalize PTB + let pt = ptb.finish(); + + // Get current gas price + let gas_price = sui_client + .read_api() + .get_reference_gas_price() + .await + .context("Failed to get reference gas price")?; + + // Get gas coin for payment + let gas_coin = Self::get_gas_coin(sui_client, active_address).await?; + + // Build transaction data + let tx_data = TransactionData::new_programmable( + active_address, + vec![gas_coin], + pt, + gas_budget, + gas_price, + ); + + // Sign transaction with intent + let keypair = keystore + .export(&active_address) + .context("Failed to export keypair from keystore")?; + + let signature = sui_types::crypto::Signature::new_secure( + &IntentMessage::new(Intent::sui_transaction(), &tx_data), + keypair, + ); + + // Execute transaction + tracing::debug!("Executing finalize session transaction..."); + let response = sui_client + .quorum_driver_api() + .execute_transaction_block( + sui_types::transaction::Transaction::from_data(tx_data, vec![signature]), + sui_sdk::rpc_types::SuiTransactionBlockResponseOptions::new().with_effects(), + None, // No execution options + ) + .await + .context("Failed to execute finalize session transaction")?; + + let digest = TxDigest::new(response.digest.to_string()); + tracing::info!("✓ Session finalized. Transaction: {}", digest.as_str()); + + Ok(digest) + } + + /// Get session object from blockchain. + /// + /// Queries the session object via Sui RPC and parses Move struct fields. + /// + /// # Arguments + /// + /// * `sui_client` - Sui RPC client (injected dependency) + /// * `session_id` - Session object ID to query + /// + /// # Returns + /// + /// GameSession struct with all fields populated from on-chain data. + /// + /// # Errors + /// + /// Returns error if: + /// - Session object ID is invalid + /// - Object cannot be fetched from RPC + /// - Object content cannot be parsed + /// - Move struct fields are missing or malformed + pub async fn get(&self, sui_client: &SuiClient, session_id: &SessionId) -> Result { + tracing::debug!("Querying session {}...", session_id.as_str()); + + // Parse session object ID + let obj_id: ObjectID = session_id + .as_str() + .parse() + .context("Invalid session ID format")?; + + // Fetch object with content + let response = sui_client + .read_api() + .get_object_with_options( + obj_id, + SuiObjectDataOptions::new().with_content().with_bcs(), + ) + .await + .context("Failed to fetch session object from RPC")?; + + let obj_data = response + .into_object() + .context("Session object not found on-chain")?; + + // Parse Move struct content + let content = obj_data + .content + .ok_or_else(|| anyhow!("Session object has no content"))?; + + // Use BCS deserialization if available, otherwise parse JSON + if let Some(bcs_bytes) = obj_data.bcs { + match bcs_bytes { + sui_sdk::rpc_types::SuiRawData::MoveObject(_move_obj) => { + // BCS deserialize the Move struct + // Note: This requires the GameSession struct to implement BCS Deserialize + // and match the on-chain Move struct layout exactly + + tracing::warn!( + "BCS deserialization not yet implemented for GameSession.\n\ + Using fallback JSON parsing instead." + ); + // Fall through to JSON parsing below + } + _ => { + return Err(anyhow!("Unexpected BCS data type for session object")); + } + } + } + + // Fallback: Parse JSON representation + if let sui_sdk::rpc_types::SuiParsedData::MoveObject(move_obj) = content { + let fields = move_obj.fields.to_json_value(); + + // Extract fields from JSON + let player = parse_address_field(&fields, "player")?; + let oracle_root = parse_bytes_field(&fields, "oracle_root")?; + let initial_state_root = parse_bytes_field(&fields, "initial_state_root")?; + let seed_commitment = parse_bytes_field(&fields, "seed_commitment")?; + let state_root = parse_bytes_field(&fields, "state_root")?; + let nonce = parse_u64_field(&fields, "nonce")?; + let pending_action_logs = parse_u64_field(&fields, "pending_action_logs")?; + let finalized = parse_bool_field(&fields, "finalized")?; + + Ok(GameSession { + id: obj_id.to_string(), + player, + oracle_root, + initial_state_root, + seed_commitment, + state_root, + nonce, + pending_action_logs, + finalized, + }) + } else { + Err(anyhow!("Session object content is not a Move object")) + } + } + + /// Get current state root for a session. + pub async fn get_state_root( + &self, + sui_client: &SuiClient, + session_id: &SessionId, + ) -> Result { + let session = self.get(sui_client, session_id).await?; + Ok(session.state_root) + } + + /// Get current nonce for a session. + pub async fn get_nonce(&self, sui_client: &SuiClient, session_id: &SessionId) -> Result { + let session = self.get(sui_client, session_id).await?; + Ok(session.nonce) + } + + /// Check if session is active (not finalized). + pub async fn is_active(&self, sui_client: &SuiClient, session_id: &SessionId) -> Result { + let session = self.get(sui_client, session_id).await?; + Ok(!session.finalized) + } +} + +// ============================================================================ +// Helper Functions for JSON Parsing +// ============================================================================ + +/// Parse address field from Move object JSON. +fn parse_address_field(fields: &serde_json::Value, field_name: &str) -> Result> { + let addr_str = fields + .get(field_name) + .and_then(|v| v.as_str()) + .ok_or_else(|| anyhow!("Missing or invalid '{}' field", field_name))?; + + // Sui addresses are hex strings like "0x..." + let addr_hex = addr_str.strip_prefix("0x").unwrap_or(addr_str); + hex::decode(addr_hex) + .with_context(|| format!("Failed to decode address field '{}'", field_name)) +} + +/// Parse bytes field (vector) from Move object JSON. +fn parse_bytes_field(fields: &serde_json::Value, field_name: &str) -> Result<[u8; 32]> { + let bytes_array = fields + .get(field_name) + .and_then(|v| v.as_array()) + .ok_or_else(|| anyhow!("Missing or invalid '{}' field", field_name))?; + + if bytes_array.len() != 32 { + return Err(anyhow!( + "Field '{}' expected 32 bytes, got {}", + field_name, + bytes_array.len() + )); + } + + let mut result = [0u8; 32]; + for (i, byte_val) in bytes_array.iter().enumerate() { + result[i] = byte_val + .as_u64() + .ok_or_else(|| anyhow!("Invalid byte value in '{}'", field_name))? + as u8; + } + + Ok(result) +} + +/// Parse u64 field from Move object JSON. +fn parse_u64_field(fields: &serde_json::Value, field_name: &str) -> Result { + fields + .get(field_name) + .and_then(|v| { + // Sui JSON can represent u64 as either number or string + v.as_u64().or_else(|| v.as_str()?.parse().ok()) + }) + .ok_or_else(|| anyhow!("Missing or invalid '{}' field", field_name)) +} + +/// Parse bool field from Move object JSON. +fn parse_bool_field(fields: &serde_json::Value, field_name: &str) -> Result { + fields + .get(field_name) + .and_then(|v| v.as_bool()) + .ok_or_else(|| anyhow!("Missing or invalid '{}' field", field_name)) +} diff --git a/crates/client/blockchain/sui/src/contracts/mod.rs b/crates/client/blockchain/sui/src/contracts/mod.rs new file mode 100644 index 0000000..1bfa752 --- /dev/null +++ b/crates/client/blockchain/sui/src/contracts/mod.rs @@ -0,0 +1,10 @@ +//! Sui Move contract integrations. +//! +//! This module contains direct integrations with on-chain Move contracts. +//! Each contract is represented as a struct with methods corresponding to +//! on-chain function calls. + +pub mod game_session; + +// Re-export contract types +pub use game_session::{GameSession, GameSessionContract}; diff --git a/crates/client/blockchain/sui/src/core/error.rs b/crates/client/blockchain/sui/src/core/error.rs new file mode 100644 index 0000000..3608b8e --- /dev/null +++ b/crates/client/blockchain/sui/src/core/error.rs @@ -0,0 +1,39 @@ +//! Error types for Sui blockchain operations. + +use thiserror::Error; + +/// Errors that can occur during Sui blockchain operations. +#[derive(Debug, Error)] +pub enum SuiError { + #[error("Network error: {0}")] + Network(String), + + #[error("Transaction failed: {0}")] + TransactionFailed(String), + + #[error("Invalid configuration: {0}")] + InvalidConfig(String), + + #[error("Session not found: {0}")] + SessionNotFound(String), + + #[error("Session is finalized and cannot be modified")] + SessionFinalized, + + #[error("Proof verification failed: {0}")] + ProofVerificationFailed(String), + + #[error("Invalid proof data: {0}")] + InvalidProof(String), + + #[error("Serialization error: {0}")] + Serialization(String), + + #[error("Object not found: {0}")] + ObjectNotFound(String), + + #[error(transparent)] + Other(#[from] anyhow::Error), +} + +pub type Result = std::result::Result; diff --git a/crates/client/blockchain/sui/src/core/mod.rs b/crates/client/blockchain/sui/src/core/mod.rs new file mode 100644 index 0000000..f6708cc --- /dev/null +++ b/crates/client/blockchain/sui/src/core/mod.rs @@ -0,0 +1,8 @@ +//! Core types and errors for Sui blockchain integration. + +pub mod error; +pub mod types; + +// Re-export commonly used items +pub use error::{Result, SuiError}; +pub use types::{ProofSubmission, SessionId, StateRoot, TxDigest}; diff --git a/crates/client/blockchain/sui/src/core/types.rs b/crates/client/blockchain/sui/src/core/types.rs new file mode 100644 index 0000000..7f0c1a5 --- /dev/null +++ b/crates/client/blockchain/sui/src/core/types.rs @@ -0,0 +1,142 @@ +//! Common types for Sui blockchain contracts. + +use serde::{Deserialize, Serialize}; + +use super::error::{Result, SuiError}; + +// ============================================================================ +// Identifiers +// ============================================================================ + +/// Session identifier (Sui ObjectID). +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub struct SessionId(pub String); + +impl SessionId { + pub fn new(object_id: String) -> Self { + Self(object_id) + } + + pub fn as_str(&self) -> &str { + &self.0 + } +} + +/// Transaction digest. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct TxDigest(pub String); + +impl TxDigest { + pub fn new(digest: String) -> Self { + Self(digest) + } + + pub fn as_str(&self) -> &str { + &self.0 + } +} + +/// State root type. +pub type StateRoot = [u8; 32]; + +// ============================================================================ +// Proof Submission +// ============================================================================ + +/// Data needed to submit a proof and update session. +#[derive(Debug, Clone)] +pub struct ProofSubmission { + /// Proof in arkworks format + pub proof_points: Vec, + + /// SHA-256 digest of journal (public input) + pub journal_digest: [u8; 32], + + /// Full journal bytes (168 bytes) + pub journal: Vec, + + /// Serialized action log (uploaded to Walrus before submission) + pub action_log: Vec, +} + +impl ProofSubmission { + /// Create proof submission from ZK proof data and action log. + /// + /// # Arguments + /// + /// * `proof` - ZK proof data (SP1/RISC0) + /// * `action_log` - Serialized action sequence (will be uploaded to Walrus) + /// + /// # Returns + /// + /// ProofSubmission ready for blockchain submission + pub fn from_proof_data(proof: &zk::ProofData, action_log: Vec) -> Result { + // Convert proof to Sui format and extract public inputs (journal) + let (proof_points, journal) = convert_sp1_proof_to_sui(proof)?; + + Ok(Self { + proof_points, + journal_digest: proof.journal_digest, + journal, + action_log, + }) + } + + /// Parse journal to extract new state values. + pub fn parse_journal(&self) -> Result<(StateRoot, u64)> { + let fields = + zk::parse_journal(&self.journal).map_err(|e| SuiError::InvalidProof(e.to_string()))?; + + Ok((fields.new_state_root, fields.new_nonce)) + } +} + +// ============================================================================ +// SP1 Proof Conversion +// ============================================================================ + +/// Convert SP1 proof to Sui arkworks format and extract journal. +/// +/// Returns (proof_points, journal) where: +/// - proof_points: Arkworks-formatted proof for Sui verification +/// - journal: 168-byte public inputs/values +#[cfg(feature = "sp1")] +fn convert_sp1_proof_to_sui(proof: &zk::ProofData) -> Result<(Vec, Vec)> { + use sp1_sdk::SP1ProofWithPublicValues; + use sp1_sui::convert_sp1_gnark_to_ark; + + if !matches!(proof.backend, zk::ProofBackend::Sp1) { + return Err(SuiError::InvalidProof(format!( + "Expected SP1 proof, got {:?}", + proof.backend + ))); + } + + let sp1_proof: SP1ProofWithPublicValues = + bincode::deserialize(&proof.bytes).map_err(|e| SuiError::Serialization(e.to_string()))?; + + // Extract journal (public values) BEFORE conversion + // This must be done before convert_sp1_gnark_to_ark consumes sp1_proof + let journal = sp1_proof.public_values.to_vec(); + + // Validate journal size + if journal.len() != 168 { + return Err(SuiError::InvalidProof(format!( + "Invalid journal size: expected 168 bytes, got {} bytes. \ + SP1 Groth16 proof does not contain valid public values.", + journal.len() + ))); + } + + // Convert to arkworks format for Sui + let (_vk, _public_inputs, proof_points) = convert_sp1_gnark_to_ark(sp1_proof); + + Ok((proof_points, journal)) +} + +#[cfg(not(feature = "sp1"))] +fn convert_sp1_proof_to_sui(_proof: &zk::ProofData) -> Result<(Vec, Vec)> { + Err(SuiError::InvalidProof( + "SP1 feature not enabled".to_string(), + )) +} diff --git a/crates/client/blockchain/sui/src/lib.rs b/crates/client/blockchain/sui/src/lib.rs new file mode 100644 index 0000000..40b37a3 --- /dev/null +++ b/crates/client/blockchain/sui/src/lib.rs @@ -0,0 +1,24 @@ +//! Sui blockchain integration for Dungeon. +//! +//! ## Module Organization +//! +//! - [`client`]: Main `SuiBlockchainClient` facade +//! - [`config`]: Network configuration and environment loading +//! - [`contracts`]: Contract clients (GameSessionContract, etc.) +//! - `deployment`: Deployment info management +//! - `error`: Error types +//! - `utils`: Utilities (transaction building, type conversion) + +pub mod client; +pub mod config; +pub mod contracts; +pub mod core; +pub mod utils; +pub mod walrus; + +// Re-export primary types +pub use client::SuiBlockchainClient; +pub use config::{DeploymentInfo, SuiConfig, SuiNetwork}; +pub use contracts::{GameSession, GameSessionContract}; +pub use core::{ProofSubmission, Result, SessionId, StateRoot, SuiError, TxDigest}; +pub use walrus::{BlobInfo, BlobObject, Network as WalrusNetwork, WalrusClient}; diff --git a/crates/client/blockchain/sui/src/utils/conversion.rs b/crates/client/blockchain/sui/src/utils/conversion.rs new file mode 100644 index 0000000..ed8e8f6 --- /dev/null +++ b/crates/client/blockchain/sui/src/utils/conversion.rs @@ -0,0 +1,200 @@ +//! Type conversion utilities for Sui blockchain. +//! +//! This module provides conversions between domain types and Sui-specific types. +//! +//! ## Conversion Categories +//! +//! 1. **Identifiers**: SessionId ↔ Sui ObjectID, TxDigest ↔ Sui Digest +//! 2. **Addresses**: Player addresses, contract addresses +//! 3. **Encoding**: Bytes ↔ Sui BCS encoding + +use crate::core::error::SuiError; +use crate::core::types::{SessionId, TxDigest}; + +// ============================================================================ +// Session ID Conversions (Adapter Pattern) +// ============================================================================ + +/// Convert SessionId to Sui object ID string. +pub fn session_id_to_object_id(session_id: &SessionId) -> &str { + session_id.as_str() +} + +/// Convert Sui object ID string to SessionId. +pub fn object_id_to_session_id(object_id: String) -> SessionId { + SessionId::new(object_id) +} + +// ============================================================================ +// Transaction ID Conversions +// ============================================================================ + +/// Convert TxDigest to string. +pub fn tx_digest_to_string(tx_digest: &TxDigest) -> &str { + tx_digest.as_str() +} + +/// Convert string to TxDigest. +pub fn string_to_tx_digest(digest: String) -> TxDigest { + TxDigest::new(digest) +} + +// ============================================================================ +// Address Conversions +// ============================================================================ + +/// Convert Sui address bytes to hex string. +/// +/// Sui addresses are 32-byte identifiers. This converts the raw bytes +/// to a hex string with "0x" prefix. +/// +/// # Arguments +/// +/// * `address_bytes` - 32-byte Sui address +/// +/// # Returns +/// +/// Hex-encoded address string. +pub fn address_to_string(address_bytes: &[u8]) -> String { + format!("0x{}", hex::encode(address_bytes)) +} + +/// Convert hex string to Sui address bytes. +/// +/// # Arguments +/// +/// * `address_str` - Hex-encoded address string +/// +/// # Returns +/// +/// 32-byte address. +/// +/// # Errors +/// +/// Returns error if: +/// - Hex decoding fails +/// - Decoded bytes are not exactly 32 bytes +pub fn string_to_address(address_str: &str) -> Result, String> { + let hex_str = address_str.strip_prefix("0x").unwrap_or(address_str); + let bytes = hex::decode(hex_str).map_err(|e| format!("Invalid address hex: {}", e))?; + + if bytes.len() != 32 { + return Err(format!("Sui address must be 32 bytes, got {}", bytes.len())); + } + + Ok(bytes) +} + +// ============================================================================ +// Encoding Utilities +// ============================================================================ + +/// Encode bytes as BCS (Binary Canonical Serialization). +/// +/// BCS is Sui's standard serialization format for Move types. +/// +/// # Arguments +/// +/// * `_data` - Data to encode (placeholder generic) +/// +/// # Returns +/// +/// BCS-encoded bytes. +/// +/// # Errors +/// +/// Returns error if serialization fails. +pub fn encode_bcs(_data: &T) -> Result, String> { + // TODO: Implement with bcs crate + // bcs::to_bytes(data).map_err(|e| format!("BCS encoding failed: {}", e)) + Err("BCS encoding not implemented".to_string()) +} + +/// Decode BCS bytes. +/// +/// # Arguments +/// +/// * `_bytes` - BCS-encoded bytes +/// +/// # Returns +/// +/// Deserialized data. +/// +/// # Errors +/// +/// Returns error if deserialization fails. +pub fn decode_bcs(_bytes: &[u8]) -> Result { + // TODO: Implement with bcs crate + // bcs::from_bytes(bytes).map_err(|e| format!("BCS decoding failed: {}", e)) + Err("BCS decoding not implemented".to_string()) +} + +// ============================================================================ +// Validation Utilities +// ============================================================================ + +/// Validate Sui object ID format. +/// +/// Checks that a string is a valid hex-encoded 32-byte object ID. +/// +/// # Arguments +/// +/// * `object_id` - Object ID string to validate +/// +/// # Returns +/// +/// `true` if valid, `false` otherwise. +pub fn is_valid_object_id(object_id: &str) -> bool { + let hex_str = object_id.strip_prefix("0x").unwrap_or(object_id); + hex::decode(hex_str).map(|b| b.len() == 32).unwrap_or(false) +} + +/// Validate Sui transaction digest format. +/// +/// Checks that a string is a valid hex-encoded 32-byte digest. +/// +/// # Arguments +/// +/// * `digest` - Digest string to validate +/// +/// # Returns +/// +/// `true` if valid, `false` otherwise. +pub fn is_valid_digest(digest: &str) -> bool { + let hex_str = digest.strip_prefix("0x").unwrap_or(digest); + hex::decode(hex_str).map(|b| b.len() == 32).unwrap_or(false) +} + +/// Validate Sui address format. +/// +/// Checks that a string is a valid hex-encoded 32-byte address. +/// +/// # Arguments +/// +/// * `address` - Address string to validate +/// +/// # Returns +/// +/// `true` if valid, `false` otherwise. +pub fn is_valid_address(address: &str) -> bool { + let hex_str = address.strip_prefix("0x").unwrap_or(address); + hex::decode(hex_str).map(|b| b.len() == 32).unwrap_or(false) +} + +// ============================================================================ +// Error Conversions +// ============================================================================ + +/// Convert Sui RPC error to SuiError. +/// +/// # Arguments +/// +/// * `_error` - Sui RPC error (placeholder) +/// +/// # Returns +/// +/// Mapped error. +pub fn sui_rpc_error_to_sui_error(_error: &()) -> SuiError { + // TODO: Implement with actual Sui error types + SuiError::Network("Unknown Sui RPC error".to_string()) +} diff --git a/crates/client/blockchain/sui/src/utils/mod.rs b/crates/client/blockchain/sui/src/utils/mod.rs new file mode 100644 index 0000000..a9dab13 --- /dev/null +++ b/crates/client/blockchain/sui/src/utils/mod.rs @@ -0,0 +1,13 @@ +//! Utility modules for Sui blockchain integration. +//! +//! This module provides common utilities for interacting with the Sui blockchain, +//! including type conversions and helper functions. +//! +//! ## Modules +//! +//! - [`conversion`]: Type conversions and validation with Adapter Pattern + +pub mod conversion; + +// Re-export commonly used items +pub use conversion::{object_id_to_session_id, session_id_to_object_id}; diff --git a/crates/client/blockchain/sui/src/walrus/client.rs b/crates/client/blockchain/sui/src/walrus/client.rs new file mode 100644 index 0000000..65f88a1 --- /dev/null +++ b/crates/client/blockchain/sui/src/walrus/client.rs @@ -0,0 +1,290 @@ +//! Walrus HTTP client implementation. + +use anyhow::{Context, Result, anyhow}; +use reqwest; + +use super::types::{BlobObject, BlobResponse, Network}; + +/// Walrus storage client using HTTP API. +/// +/// This client provides simple blob storage/retrieval operations using +/// Walrus's public HTTP endpoints. +pub struct WalrusClient { + /// Publisher endpoint (for storing blobs) + publisher_url: String, + + /// Aggregator endpoint (for retrieving blobs) + aggregator_url: String, + + /// HTTP client + http_client: reqwest::Client, + + /// Network + network: Network, +} + +impl WalrusClient { + /// Create client for Walrus testnet. + pub fn testnet() -> Self { + Self::new(Network::Testnet) + } + + /// Create client for specific network. + pub fn new(network: Network) -> Self { + Self { + publisher_url: network.publisher_url().to_string(), + aggregator_url: network.aggregator_url().to_string(), + http_client: reqwest::Client::new(), + network, + } + } + + /// Store blob in Walrus and return Blob object metadata. + /// + /// # Arguments + /// + /// * `data` - Blob data to store + /// * `epochs` - Number of epochs to store blob + /// * `recipient` - Sui address to receive the Blob object (optional) + /// + /// # Returns + /// + /// BlobObject with Sui object ID and Walrus blob ID + /// + /// # Errors + /// + /// Returns error if: + /// - Network request fails + /// - Walrus returns error response + /// - Response parsing fails + pub async fn store_blob( + &self, + data: &[u8], + epochs: u64, + recipient: Option<&str>, + ) -> Result { + // Build URL with query parameters + let mut url = format!("{}/v1/blobs?epochs={}", self.publisher_url, epochs); + + // Add recipient address if specified + if let Some(addr) = recipient { + url.push_str(&format!("&send_object_to={}", addr)); + } + + tracing::debug!( + "Uploading blob to Walrus: {} bytes, {} epochs, recipient={:?}", + data.len(), + epochs, + recipient + ); + + let response = self + .http_client + .put(&url) + .header("Content-Type", "application/octet-stream") + .body(data.to_vec()) + .send() + .await + .context("Failed to send blob upload request to Walrus")?; + + let status = response.status(); + if !status.is_success() { + let error_text = response + .text() + .await + .unwrap_or_else(|_| "Unknown error".to_string()); + return Err(anyhow!( + "Walrus upload failed with status {}: {}", + status, + error_text + )); + } + + // Get response text first for better error reporting + let response_text = response + .text() + .await + .context("Failed to read Walrus response body")?; + + tracing::debug!("Walrus response: {}", response_text); + + // Parse response + let blob_response: BlobResponse = + serde_json::from_str(&response_text).with_context(|| { + format!( + "Failed to parse Walrus upload response. Raw response: {}", + response_text + ) + })?; + + match blob_response { + BlobResponse::NewlyCreated(info) => { + tracing::info!( + "✓ Blob uploaded to Walrus: {} (size: {} bytes, cost: {} MIST)", + info.blob_object.blob_id, + info.blob_object.size, + info.cost + ); + Ok(info.blob_object) + } + BlobResponse::AlreadyCertified { blob_id, end_epoch } => { + tracing::info!( + "✓ Blob already exists in Walrus: {} (expires epoch: {})", + blob_id, + end_epoch + ); + // For cached blobs, we don't have object ID + // This is a limitation - we'd need to query Sui to get object ID + Err(anyhow!( + "Blob already exists but object ID not available. \ + Blob ID: {}. This is a known limitation - consider using a unique \ + blob per upload or querying Sui for object ID.", + blob_id + )) + } + } + } + + /// Retrieve blob data by Walrus blob ID. + /// + /// # Arguments + /// + /// * `blob_id` - Walrus blob ID (base64-encoded) + /// + /// # Returns + /// + /// Blob data as bytes + /// + /// # Errors + /// + /// Returns error if: + /// - Network request fails + /// - Blob not found + /// - Download fails + pub async fn get_blob(&self, blob_id: &str) -> Result> { + let url = format!("{}/v1/blobs/{}", self.aggregator_url, blob_id); + + tracing::debug!("Downloading blob from Walrus: {}", blob_id); + + let response = self + .http_client + .get(&url) + .send() + .await + .context("Failed to send blob download request to Walrus")?; + + let status = response.status(); + if !status.is_success() { + let error_text = response + .text() + .await + .unwrap_or_else(|_| "Unknown error".to_string()); + return Err(anyhow!( + "Walrus download failed with status {}: {}", + status, + error_text + )); + } + + let data = response + .bytes() + .await + .context("Failed to read blob data from Walrus")? + .to_vec(); + + tracing::debug!("✓ Blob downloaded from Walrus: {} bytes", data.len()); + + Ok(data) + } + + /// Retrieve blob data by Sui object ID. + /// + /// This is useful when you have the Blob object ID from a transaction + /// but not the Walrus blob ID. + /// + /// # Arguments + /// + /// * `object_id` - Sui object ID (hex-encoded) + /// + /// # Returns + /// + /// Blob data as bytes + pub async fn get_blob_by_object_id(&self, object_id: &str) -> Result> { + let url = format!( + "{}/v1/blobs/by-object-id/{}", + self.aggregator_url, object_id + ); + + tracing::debug!("Downloading blob by object ID: {}", object_id); + + let response = self + .http_client + .get(&url) + .send() + .await + .context("Failed to send blob download request to Walrus")?; + + let status = response.status(); + if !status.is_success() { + let error_text = response + .text() + .await + .unwrap_or_else(|_| "Unknown error".to_string()); + return Err(anyhow!( + "Walrus download failed with status {}: {}", + status, + error_text + )); + } + + let data = response + .bytes() + .await + .context("Failed to read blob data from Walrus")? + .to_vec(); + + tracing::debug!("✓ Blob downloaded from Walrus: {} bytes", data.len()); + + Ok(data) + } + + /// Get network configuration. + pub fn network(&self) -> Network { + self.network + } + + /// Get publisher URL. + pub fn publisher_url(&self) -> &str { + &self.publisher_url + } + + /// Get aggregator URL. + pub fn aggregator_url(&self) -> &str { + &self.aggregator_url + } +} + +impl Default for WalrusClient { + fn default() -> Self { + Self::testnet() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_client_creation() { + let client = WalrusClient::testnet(); + assert_eq!(client.network(), Network::Testnet); + assert_eq!( + client.publisher_url(), + "https://publisher.walrus-testnet.walrus.space" + ); + assert_eq!( + client.aggregator_url(), + "https://aggregator.walrus-testnet.walrus.space" + ); + } +} diff --git a/crates/client/blockchain/sui/src/walrus/mod.rs b/crates/client/blockchain/sui/src/walrus/mod.rs new file mode 100644 index 0000000..d0de275 --- /dev/null +++ b/crates/client/blockchain/sui/src/walrus/mod.rs @@ -0,0 +1,31 @@ +//! Walrus decentralized storage integration. +//! +//! This module provides integration with Walrus, a decentralized blob store +//! built on Sui for coordination and governance. +//! +//! ## Overview +//! +//! Walrus stores large binary files (blobs) in a decentralized network while +//! using Sui smart contracts for: +//! - Proof of availability +//! - Storage duration management +//! - Access control via Blob objects +//! +//! ## Integration Pattern +//! +//! We use Walrus HTTP API for simplicity and stability: +//! 1. Upload blob via Publisher endpoint → get Blob object ID +//! 2. Pass Blob object to Move contract (game_session::update) +//! 3. Contract verifies blob availability on-chain +//! +//! ## Modules +//! +//! - [`client`]: HTTP client for Walrus storage operations +//! - [`types`]: Walrus-specific types (BlobObject, BlobInfo, etc.) + +pub mod client; +pub mod types; + +// Re-export primary types +pub use client::WalrusClient; +pub use types::{BlobInfo, BlobObject, BlobResponse, Network}; diff --git a/crates/client/blockchain/sui/src/walrus/types.rs b/crates/client/blockchain/sui/src/walrus/types.rs new file mode 100644 index 0000000..92df527 --- /dev/null +++ b/crates/client/blockchain/sui/src/walrus/types.rs @@ -0,0 +1,168 @@ +//! Walrus type definitions. +//! +//! # Resilience to API Changes +//! +//! These types are designed to be resilient to Walrus API changes: +//! - Most fields are `Option` with `#[serde(default)]` to handle missing fields +//! - `#[serde(flatten)]` catches unknown fields in `extra: HashMap` +//! - Only critical fields (`id`, `blob_id`) are required +//! +//! This approach prevents deserialization failures when: +//! - Walrus adds new fields (captured in `extra`) +//! - Walrus makes fields nullable +//! - Walrus changes field types (gracefully defaults to 0 or None) + +use serde::{Deserialize, Serialize}; + +/// Walrus network configuration. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] +pub enum Network { + /// Testnet (public) + #[default] + Testnet, + /// Mainnet (future) + Mainnet, +} + +impl Network { + /// Get publisher URL for this network. + pub fn publisher_url(&self) -> &'static str { + match self { + Network::Testnet => "https://publisher.walrus-testnet.walrus.space", + Network::Mainnet => "https://publisher.walrus-mainnet.walrus.space", // Future + } + } + + /// Get aggregator URL for this network. + pub fn aggregator_url(&self) -> &'static str { + match self { + Network::Testnet => "https://aggregator.walrus-testnet.walrus.space", + Network::Mainnet => "https://aggregator.walrus-mainnet.walrus.space", // Future + } + } +} + +/// Response from storing a blob in Walrus. +#[derive(Debug, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub enum BlobResponse { + /// Blob was newly created + NewlyCreated(Box), + /// Blob already exists (cached) + AlreadyCertified { blob_id: String, end_epoch: u64 }, +} + +impl BlobResponse { + /// Get blob object (only available for newly created blobs). + pub fn blob_object(&self) -> Option<&BlobObject> { + match self { + BlobResponse::NewlyCreated(info) => Some(&info.blob_object), + BlobResponse::AlreadyCertified { .. } => None, + } + } + + /// Get blob ID. + pub fn blob_id(&self) -> &str { + match self { + BlobResponse::NewlyCreated(info) => &info.blob_object.blob_id, + BlobResponse::AlreadyCertified { blob_id, .. } => blob_id, + } + } +} + +/// Information about a newly created blob. +#[derive(Debug, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct BlobInfo { + /// Blob object metadata + pub blob_object: BlobObject, + + /// Storage cost in MIST + #[serde(default)] + pub cost: u64, + + /// Catch-all for unknown fields (resource_operation, etc.) + #[serde(flatten)] + pub extra: std::collections::HashMap, +} + +/// Walrus blob object (stored on Sui). +/// +/// This represents the on-chain Sui object that references the off-chain blob data. +/// +/// **Design**: Most fields are optional to handle API changes gracefully. +/// Only `id` and `blob_id` are required for core functionality. +#[derive(Debug, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct BlobObject { + /// Sui object ID (used to reference blob in Move contracts) - REQUIRED + pub id: String, + + /// Walrus blob ID (base64-encoded, used for HTTP retrieval) - REQUIRED + pub blob_id: String, + + /// Blob size in bytes + #[serde(default)] + pub size: u64, + + /// Encoding type (e.g., "RS2" for Reed-Solomon erasure coding) + #[serde(default, skip_serializing_if = "Option::is_none")] + pub encoding_type: Option, + + /// Epoch when blob was registered + #[serde(default, skip_serializing_if = "Option::is_none")] + pub registered_epoch: Option, + + /// Epoch when blob was certified (optional, null for newly uploaded blobs) + #[serde(default, skip_serializing_if = "Option::is_none")] + pub certified_epoch: Option, + + /// Storage information (contains start_epoch and end_epoch) + #[serde(default, skip_serializing_if = "Option::is_none")] + pub storage: Option, + + /// Whether the blob is deletable + #[serde(default)] + pub deletable: bool, + + /// Catch-all for unknown fields (prevents future API changes from breaking) + #[serde(flatten)] + pub extra: std::collections::HashMap, +} + +/// Storage information for a Walrus blob. +#[derive(Debug, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct StorageInfo { + /// Storage object ID + #[serde(default, skip_serializing_if = "Option::is_none")] + pub id: Option, + + /// Epoch when storage starts + #[serde(default)] + pub start_epoch: u64, + + /// Epoch when storage expires + #[serde(default)] + pub end_epoch: u64, + + /// Total storage size (in some unit) + #[serde(default)] + pub storage_size: u64, + + /// Catch-all for unknown fields + #[serde(flatten)] + pub extra: std::collections::HashMap, +} + +impl BlobObject { + /// Get Sui object ID. + pub fn object_id(&self) -> &str { + &self.id + } + + /// Get Walrus blob ID (for HTTP retrieval). + pub fn blob_id(&self) -> &str { + &self.blob_id + } +} diff --git a/crates/client/bootstrap/Cargo.toml b/crates/client/bootstrap/Cargo.toml index fefa822..88ee287 100644 --- a/crates/client/bootstrap/Cargo.toml +++ b/crates/client/bootstrap/Cargo.toml @@ -5,11 +5,14 @@ edition = "2024" [features] # ZK backend features (propagate to runtime) -default = ["risc0"] +# No default - backend must be explicitly selected +default = [] risc0 = ["runtime/risc0"] stub = ["runtime/stub"] sp1 = ["runtime/sp1"] arkworks = ["runtime/arkworks"] +# Blockchain integration +sui = ["runtime/sui"] [dependencies] anyhow = { workspace = true } diff --git a/crates/client/bootstrap/src/builder.rs b/crates/client/bootstrap/src/builder.rs index 2c8cc24..2897dec 100644 --- a/crates/client/bootstrap/src/builder.rs +++ b/crates/client/bootstrap/src/builder.rs @@ -5,34 +5,70 @@ use std::sync::Arc; use anyhow::Result; use runtime::{AiKind, ProviderKind, Runtime, Scenario}; -use crate::config::ClientConfig; +use crate::config::RuntimeConfig; use crate::oracles::{ContentOracleFactory, OracleBundle, OracleFactory}; /// Builder that assembles runtime state, oracles, and configuration for clients. pub struct RuntimeBuilder { - config: ClientConfig, oracle_factory: Arc, + config: RuntimeConfig, + initial_state: Option, + #[cfg(feature = "sui")] + blockchain_clients: Option, +} + +impl Default for RuntimeBuilder { + fn default() -> Self { + Self::new() + } } impl RuntimeBuilder { - /// Create a new RuntimeBuilder with data-driven content from game-content. + /// Create a new RuntimeBuilder with default configuration. /// /// This uses ContentOracleFactory by default, loading content from RON/TOML files. /// Use `oracle_factory()` to override with a custom factory. - pub fn new(config: ClientConfig) -> Self { + /// Use `config()` to provide runtime configuration. + pub fn new() -> Self { let default_factory = ContentOracleFactory::default_paths(); Self { - config, oracle_factory: Arc::new(default_factory), + config: RuntimeConfig::default(), + initial_state: None, + #[cfg(feature = "sui")] + blockchain_clients: None, } } + /// Provide runtime configuration. + pub fn config(mut self, config: RuntimeConfig) -> Self { + self.config = config; + self + } + /// Provide a custom oracle factory (e.g., game-content backed implementation). pub fn oracle_factory(mut self, factory: impl OracleFactory + 'static) -> Self { self.oracle_factory = Arc::new(factory); self } + /// Provide initial game state (for resuming existing session). + /// + /// If provided, this state will be used instead of creating a new state from scenario. + pub fn initial_state(mut self, state: game_core::GameState) -> Self { + self.initial_state = Some(state); + self + } + + /// Set blockchain clients for manual blockchain operations (Sui feature only). + /// + /// This enables RuntimeHandle methods for uploading to Walrus and submitting to blockchain. + #[cfg(feature = "sui")] + pub fn blockchain_clients(mut self, clients: runtime::BlockchainClients) -> Self { + self.blockchain_clients = Some(clients); + self + } + /// Find scenario file path. /// /// Looks for test_scenario.ron in the data directory. @@ -65,25 +101,30 @@ impl RuntimeBuilder { pub async fn build(self) -> Result { let oracles = self.oracle_factory.build(); - let manager = oracles.manager(); - - let mut builder = Runtime::builder().oracles(manager.clone()); - - // Load scenario if available - // Try to find scenario file in data directory - let scenario_path = self.find_scenario_path(); - if let Some(path) = scenario_path { - match Scenario::load_from_file(&path) { - Ok(scenario) => { - tracing::info!("Loaded scenario from {}", path.display()); - builder = builder.scenario(scenario); - } - Err(e) => { - tracing::warn!("Failed to load scenario from {}: {}", path.display(), e); + + let mut builder = Runtime::builder().oracles(oracles.clone()); + + // Use initial_state if provided (for session resumption) + if let Some(state) = self.initial_state { + tracing::info!("Using provided initial state (session resumption)"); + builder = builder.initial_state(state); + } else { + // Load scenario if available + // Try to find scenario file in data directory + let scenario_path = self.find_scenario_path(); + if let Some(path) = scenario_path { + match Scenario::load_from_file(&path) { + Ok(scenario) => { + tracing::info!("Loaded scenario from {}", path.display()); + builder = builder.scenario(scenario); + } + Err(e) => { + tracing::warn!("Failed to load scenario from {}: {}", path.display(), e); + } } + } else { + tracing::info!("No scenario file found, using default state"); } - } else { - tracing::info!("No scenario file found, using default state"); } // Enable proving if requested @@ -107,26 +148,29 @@ impl RuntimeBuilder { builder = builder.checkpoint_interval(interval); } + // Set blockchain clients if provided (Sui feature only) + #[cfg(feature = "sui")] + if let Some(blockchain_clients) = self.blockchain_clients { + builder = builder.blockchain_clients(blockchain_clients); + } + // Build the runtime let runtime = builder.build().await?; // Register AI providers let handle = runtime.handle(); - // Register GoalBasedAiProvider (recommended) - // This provider uses goal-oriented decision making (Goal → Evaluate candidates → Select best) - // Simpler and more natural than the layered Intent → Tactic → Action approach - let goal_based_kind = ProviderKind::Ai(AiKind::GoalBased); - handle.register_provider(goal_based_kind, runtime::GoalBasedAiProvider::new())?; - - // Register UtilityAiProvider (legacy, for comparison) - // This provider uses 3-layer decision making (Intent → Tactic → Action) - // Note: Currently has compilation errors due to old action system - // let utility_ai_kind = ProviderKind::Ai(AiKind::Utility); - // handle.register_provider(utility_ai_kind, runtime::UtilityAiProvider::new())?; + // Register UtilityAiProvider (goal-directed with utility scoring) + // This provider uses: + // 1. Goal Selection (Attack, Flee, Heal, Idle, etc.) + // 2. Candidate Generation (all possible actions) + // 3. Utility Scoring (0-100 based on goal relevance) + // 4. Best Selection (highest score wins) + let utility_ai_kind = ProviderKind::Ai(AiKind::Utility); + handle.register_provider(utility_ai_kind, runtime::UtilityAiProvider::new())?; - // Set GoalBased as default for all NPCs - handle.set_default_provider(goal_based_kind)?; + // Set Utility AI as default for all NPCs + handle.set_default_provider(utility_ai_kind)?; Ok(RuntimeSetup { config: self.config, @@ -137,7 +181,7 @@ impl RuntimeBuilder { } pub struct RuntimeSetup { - pub config: ClientConfig, + pub config: RuntimeConfig, pub oracles: OracleBundle, pub runtime: Runtime, } diff --git a/crates/client/bootstrap/src/config.rs b/crates/client/bootstrap/src/config.rs index 7c7f1ed..b92a6f2 100644 --- a/crates/client/bootstrap/src/config.rs +++ b/crates/client/bootstrap/src/config.rs @@ -1,25 +1,27 @@ -//! Client runtime configuration structures and loaders. +//! Runtime configuration structures and loaders. +//! +//! This module contains runtime-specific configuration (proving, persistence, etc.) +//! that is shared across all client types. + use std::env; +use std::path::PathBuf; -/// Configuration required to bootstrap a client runtime. +/// Configuration for runtime initialization. /// -/// This is cross-frontend configuration shared by CLI, GUI, and other clients. +/// This contains only runtime-related settings (ZK proving, persistence, session management). +/// UI-specific configuration has been moved to `client-frontend-core::FrontendConfig`. #[derive(Clone, Debug, Default)] -pub struct ClientConfig { - pub channels: ChannelConfig, - pub messages: MessageConfig, +pub struct RuntimeConfig { pub enable_proving: bool, pub enable_persistence: bool, pub session_id: Option, - pub save_data_dir: Option, + pub save_data_dir: Option, pub checkpoint_interval: Option, } -impl ClientConfig { - pub const fn new(channels: ChannelConfig, messages: MessageConfig) -> Self { +impl RuntimeConfig { + pub const fn new() -> Self { Self { - channels, - messages, enable_proving: false, enable_persistence: false, session_id: None, @@ -36,47 +38,9 @@ impl ClientConfig { /// - `GAME_SESSION_ID` - Session identifier for save files (default: auto-generated) /// - `SAVE_DATA_DIR` - Directory for save data (default: platform-specific) /// - `CHECKPOINT_INTERVAL` - Actions between checkpoints (default: 10) - /// - `CLI_ACTION_BUFFER` - Action queue size (default: 10) - /// - `CLI_MESSAGE_CAPACITY` - Message log capacity (default: 64) - /// - `SHOW_DAMAGE_MESSAGES` - Show damage effect messages (default: true) - /// - `SHOW_HEALING_MESSAGES` - Show healing effect messages (default: true) - /// - `SHOW_MOVEMENT_MESSAGES` - Show movement effect messages (default: false) - /// - `SHOW_STATUS_MESSAGES` - Show status effect messages (default: true) - /// - `SHOW_RESOURCE_MESSAGES` - Show resource change messages (default: false) - /// - `SHOW_SUMMON_MESSAGES` - Show summon messages (default: true) pub fn from_env() -> Self { let mut config = Self::default(); - // Channel configuration - if let Some(capacity) = read_env::("CLI_ACTION_BUFFER") { - config.channels.action_buffer = capacity.max(1); - } - - // Message configuration - if let Some(capacity) = read_env::("CLI_MESSAGE_CAPACITY") { - config.messages.capacity = capacity.max(1); - } - - // Effect visibility settings - if let Some(show) = read_env_bool("SHOW_DAMAGE_MESSAGES") { - config.messages.effect_visibility.show_damage = show; - } - if let Some(show) = read_env_bool("SHOW_HEALING_MESSAGES") { - config.messages.effect_visibility.show_healing = show; - } - if let Some(show) = read_env_bool("SHOW_MOVEMENT_MESSAGES") { - config.messages.effect_visibility.show_movement = show; - } - if let Some(show) = read_env_bool("SHOW_STATUS_MESSAGES") { - config.messages.effect_visibility.show_status = show; - } - if let Some(show) = read_env_bool("SHOW_RESOURCE_MESSAGES") { - config.messages.effect_visibility.show_resource = show; - } - if let Some(show) = read_env_bool("SHOW_SUMMON_MESSAGES") { - config.messages.effect_visibility.show_summon = show; - } - // Enable ZK proving if environment variable is set if let Some(enable) = read_env::("ENABLE_ZK_PROVING") { config.enable_proving = enable; @@ -95,8 +59,11 @@ impl ClientConfig { // Session ID (optional) config.session_id = env::var("GAME_SESSION_ID").ok(); - // Save data directory (optional) - config.save_data_dir = env::var("SAVE_DATA_DIR").ok().map(std::path::PathBuf::from); + // Save data directory (from environment or platform default) + config.save_data_dir = env::var("SAVE_DATA_DIR") + .ok() + .map(PathBuf::from) + .or_else(get_default_save_data_dir); // Checkpoint interval (optional) config.checkpoint_interval = read_env::("CHECKPOINT_INTERVAL"); @@ -105,82 +72,55 @@ impl ClientConfig { } } -#[derive(Clone, Debug)] -pub struct ChannelConfig { - pub action_buffer: usize, -} - -impl Default for ChannelConfig { - fn default() -> Self { - Self { action_buffer: 10 } +/// Get the platform-specific default save data directory. +fn get_default_save_data_dir() -> Option { + #[cfg(target_os = "macos")] + { + if let Some(home) = env::var_os("HOME") { + let mut path = PathBuf::from(home); + path.push("Library"); + path.push("Application Support"); + path.push("dungeon"); + path.push("saves"); + return Some(path); + } } -} - -#[derive(Clone, Debug)] -pub struct MessageConfig { - pub capacity: usize, - pub effect_visibility: EffectVisibility, -} -impl Default for MessageConfig { - fn default() -> Self { - Self { - capacity: 64, - effect_visibility: EffectVisibility::default(), + #[cfg(target_os = "linux")] + { + if let Some(xdg_data) = env::var_os("XDG_DATA_HOME") { + let mut path = PathBuf::from(xdg_data); + path.push("dungeon"); + path.push("saves"); + return Some(path); + } else if let Some(home) = env::var_os("HOME") { + let mut path = PathBuf::from(home); + path.push(".local"); + path.push("share"); + path.push("dungeon"); + path.push("saves"); + return Some(path); } } -} - -/// Controls which effect types generate visible messages. -/// -/// This is cross-frontend configuration - both CLI and GUI clients -/// can use this to filter which effects to display in their message logs. -#[derive(Clone, Debug)] -pub struct EffectVisibility { - /// Show damage effects (e.g., "Goblin#5 takes 12 damage"). - pub show_damage: bool, - /// Show healing effects (e.g., "Player heals 15 HP"). - pub show_healing: bool, - /// Show movement effects (e.g., "Player moves north"). - pub show_movement: bool, - /// Show status effects (e.g., "Goblin#5 is poisoned for 3 turns"). - pub show_status: bool, - /// Show resource changes (e.g., "Player gains 10 MP"). - pub show_resource: bool, - /// Show summon effects (e.g., "Wizard summons Skeleton#3"). - pub show_summon: bool, -} -impl Default for EffectVisibility { - fn default() -> Self { - Self { - show_damage: true, - show_healing: true, - show_movement: false, // Movement is visually obvious on map - show_status: true, - show_resource: false, // Resource changes shown in stats panel - show_summon: true, + #[cfg(target_os = "windows")] + { + if let Some(local_appdata) = env::var_os("LOCALAPPDATA") { + let mut path = PathBuf::from(local_appdata); + path.push("dungeon"); + path.push("saves"); + return Some(path); } } -} -impl EffectVisibility { - /// Returns true if messages should be generated for this effect. - pub fn should_show(&self, applied_value: &game_core::action::AppliedValue) -> bool { - use game_core::action::AppliedValue; - - match applied_value { - AppliedValue::Damage { .. } => self.show_damage, - AppliedValue::Healing { .. } => self.show_healing, - AppliedValue::Movement { .. } => self.show_movement, - AppliedValue::StatusApplied { .. } | AppliedValue::StatusRemoved { .. } => { - self.show_status - } - AppliedValue::ResourceChange { .. } => self.show_resource, - AppliedValue::Summon { .. } => self.show_summon, - AppliedValue::None => false, // Never show empty effects - } + // Fallback for other platforms + #[cfg(not(any(target_os = "macos", target_os = "linux", target_os = "windows")))] + { + Some(PathBuf::from("/tmp/dungeon/saves")) } + + #[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))] + None } fn read_env(key: &str) -> Option @@ -189,11 +129,3 @@ where { env::var(key).ok()?.parse().ok() } - -fn read_env_bool(key: &str) -> Option { - match env::var(key).ok()?.to_lowercase().as_str() { - "true" | "1" | "yes" | "on" => Some(true), - "false" | "0" | "no" | "off" => Some(false), - _ => None, - } -} diff --git a/crates/client/bootstrap/src/lib.rs b/crates/client/bootstrap/src/lib.rs index 1909b8a..8c24968 100644 --- a/crates/client/bootstrap/src/lib.rs +++ b/crates/client/bootstrap/src/lib.rs @@ -5,7 +5,9 @@ pub mod builder; pub mod config; pub mod oracles; +pub mod session; pub use builder::{RuntimeBuilder, RuntimeSetup}; -pub use config::ClientConfig; +pub use config::RuntimeConfig; pub use oracles::{ContentOracleFactory, OracleBundle, OracleFactory}; +pub use session::{SessionInfo, find_latest_session, list_sessions, load_latest_state}; diff --git a/crates/client/bootstrap/src/oracles.rs b/crates/client/bootstrap/src/oracles.rs index eebe72f..43083bd 100644 --- a/crates/client/bootstrap/src/oracles.rs +++ b/crates/client/bootstrap/src/oracles.rs @@ -2,32 +2,10 @@ use std::path::PathBuf; use std::sync::Arc; -use runtime::{ - ActorOracleImpl, ConfigOracleImpl, ItemOracleImpl, MapOracleImpl, OracleManager, - TablesOracleImpl, -}; - -/// Bundle of oracle implementations that the runtime consumes. -#[derive(Clone)] -pub struct OracleBundle { - pub map: Arc, - pub items: Arc, - pub tables: Arc, - pub actors: Arc, - pub config: Arc, -} +use runtime::{ActionOracleImpl, ActorOracleImpl, ConfigOracleImpl, ItemOracleImpl, MapOracleImpl}; -impl OracleBundle { - pub fn manager(&self) -> OracleManager { - OracleManager::new( - Arc::clone(&self.map), - Arc::clone(&self.items), - Arc::clone(&self.tables), - Arc::clone(&self.actors), - Arc::clone(&self.config), - ) - } -} +// Re-export OracleBundle from runtime +pub use runtime::OracleBundle; pub trait OracleFactory: Send + Sync { fn build(&self) -> OracleBundle; @@ -102,32 +80,9 @@ impl ContentOracleFactory { } } -// Convert game-content's ProviderKindSpec to runtime's ProviderKind -fn convert_provider_kind(spec: game_content::ProviderKindSpec) -> runtime::ProviderKind { - use game_content::{AiKindSpec, InteractiveKindSpec, ProviderKindSpec}; - use runtime::{AiKind, InteractiveKind, ProviderKind}; - - match spec { - ProviderKindSpec::Interactive(i) => ProviderKind::Interactive(match i { - InteractiveKindSpec::CliInput => InteractiveKind::CliInput, - InteractiveKindSpec::NetworkInput => InteractiveKind::NetworkInput, - InteractiveKindSpec::Replay => InteractiveKind::Replay, - }), - ProviderKindSpec::Ai(a) => ProviderKind::Ai(match a { - AiKindSpec::Wait => AiKind::Wait, - AiKindSpec::Aggressive => AiKind::Aggressive, - AiKindSpec::Passive => AiKind::Passive, - AiKindSpec::Scripted => AiKind::Scripted, - AiKindSpec::Utility => AiKind::Utility, - }), - ProviderKindSpec::Custom(id) => ProviderKind::Custom(id), - } -} - impl OracleFactory for ContentOracleFactory { fn build(&self) -> OracleBundle { use game_content::ContentFactory; - use runtime::AiConfig; // Verify data directory exists if !self.data_dir.exists() { @@ -190,17 +145,11 @@ impl OracleFactory for ContentOracleFactory { ) }); - // Build actor oracle with templates and AI configs + // Build actor oracle with templates (trait profiles already resolved by ActorLoader) let mut actor_oracle = ActorOracleImpl::new(); - for (actor_id, template, provider_spec, trait_profile) in actor_data { - // Convert ProviderKindSpec to runtime::ProviderKind - let provider = convert_provider_kind(provider_spec); - - let ai_config = AiConfig { - traits: trait_profile, - default_provider: provider, - }; - actor_oracle.add(actor_id, template, ai_config); + for (actor_id, template) in actor_data { + // ActorLoader has already resolved trait_profile and set it in template + actor_oracle.add(actor_id, template); } // Build item oracle @@ -213,15 +162,15 @@ impl OracleFactory for ContentOracleFactory { let map_oracle = MapOracleImpl::new(dimensions, tiles); // Build other oracles - let tables_oracle = TablesOracleImpl::new(); + let actions_oracle = ActionOracleImpl::new(); let config_oracle = ConfigOracleImpl::new(config); - OracleBundle { - map: Arc::new(map_oracle), - items: Arc::new(item_oracle), - tables: Arc::new(tables_oracle), - actors: Arc::new(actor_oracle), - config: Arc::new(config_oracle), - } + OracleBundle::new( + Arc::new(map_oracle), + Arc::new(item_oracle), + Arc::new(actions_oracle), + Arc::new(actor_oracle), + Arc::new(config_oracle), + ) } } diff --git a/crates/client/bootstrap/src/session.rs b/crates/client/bootstrap/src/session.rs new file mode 100644 index 0000000..720e1a1 --- /dev/null +++ b/crates/client/bootstrap/src/session.rs @@ -0,0 +1,122 @@ +//! Session management utilities for resuming games. + +use anyhow::{Context, Result, anyhow}; +use std::path::Path; + +use game_core::GameState; +use runtime::StateRepository; + +/// Information about a saved session. +#[derive(Debug, Clone, PartialEq)] +pub struct SessionInfo { + /// Session directory name (e.g., "session_1234567890") + pub session_id: String, + + /// Session timestamp extracted from directory name + pub timestamp: u64, + + /// Latest state nonce available in this session + pub latest_nonce: u64, +} + +/// List all session directories in the save data directory. +/// +/// Sessions are identified by directories matching "session_" format. +pub fn list_sessions(base_dir: &Path) -> Result> { + if !base_dir.exists() { + return Ok(Vec::new()); + } + + let mut sessions = Vec::new(); + + for entry in std::fs::read_dir(base_dir)? { + let entry = entry?; + if !entry.file_type()?.is_dir() { + continue; + } + + let dir_name = entry.file_name(); + let name = dir_name + .to_str() + .context("Invalid UTF-8 in directory name")?; + + // Extract timestamp from session_ format + let timestamp = if let Some(stripped) = name.strip_prefix("session_") { + stripped.parse::().ok() + } else { + // Also support plain numeric session IDs for backwards compatibility + name.parse::().ok() + }; + + if let Some(timestamp) = timestamp { + // Find latest nonce in this session + let session_dir = entry.path(); + let states_dir = session_dir.join("states"); + + let latest_nonce = find_highest_state_nonce(&states_dir).unwrap_or(0); + + sessions.push(SessionInfo { + session_id: name.to_string(), + timestamp, + latest_nonce, + }); + } + } + + // Sort by timestamp (descending) - most recent first + sessions.sort_by(|a, b| b.timestamp.cmp(&a.timestamp)); + + Ok(sessions) +} + +/// Find the most recent session by timestamp. +pub fn find_latest_session(base_dir: &Path) -> Result> { + let sessions = list_sessions(base_dir)?; + Ok(sessions.into_iter().next()) +} + +/// Find the highest nonce state file in a states directory. +fn find_highest_state_nonce(states_dir: &Path) -> Option { + if !states_dir.exists() { + return None; + } + + let mut max_nonce = None; + + for entry in std::fs::read_dir(states_dir).ok()? { + let entry = entry.ok()?; + let filename = entry.file_name(); + let name = filename.to_str()?; + + // Files are named: state_.bin + if let Some(stripped) = name + .strip_prefix("state_") + .and_then(|s| s.strip_suffix(".bin")) + && let Ok(nonce) = stripped.parse::() + { + max_nonce = Some(max_nonce.map_or(nonce, |n: u64| n.max(nonce))); + } + } + + max_nonce +} + +/// Load the latest state from a session directory. +/// +/// Returns the highest nonce state available, or None if no states exist. +pub fn load_latest_state(base_dir: &Path, session_id: &str) -> Result> { + let states_dir = base_dir.join(session_id).join("states"); + + let nonce = match find_highest_state_nonce(&states_dir) { + Some(n) => n, + None => return Ok(None), + }; + + // Use FileStateRepository to load the state + let state_repo = runtime::FileStateRepository::new(states_dir)?; + let state = state_repo + .load(nonce)? + .ok_or_else(|| anyhow!("State file exists but failed to load: state_{}.bin", nonce))?; + + Ok(Some((nonce, state))) +} diff --git a/crates/client/cli/src/app.rs b/crates/client/cli/src/app.rs deleted file mode 100644 index e40405c..0000000 --- a/crates/client/cli/src/app.rs +++ /dev/null @@ -1,149 +0,0 @@ -//! Glue code tying the runtime, oracles, and terminal UI together. -use anyhow::Result; -use async_trait::async_trait; -use tokio::sync::mpsc; - -use game_core::{Action, EntityId}; -use runtime::{InteractiveKind, ProviderKind, Runtime, Topic}; - -use crate::event::{CliEventConsumer, EventLoop}; -use crate::input::CliActionProvider; -use crate::presentation::terminal; -use client_bootstrap::{ - ClientConfig, - builder::{RuntimeBuilder, RuntimeSetup}, - oracles::OracleBundle, -}; -use client_core::{frontend::FrontendApp, message::MessageLog}; - -pub struct CliApp { - client_config: ClientConfig, - cli_config: crate::config::CliConfig, - oracles: OracleBundle, - runtime: Runtime, -} - -pub struct CliAppBuilder { - cli_config: crate::config::CliConfig, - bootstrap: RuntimeBuilder, -} - -impl CliAppBuilder { - pub fn new(client_config: ClientConfig, cli_config: crate::config::CliConfig) -> Self { - Self { - cli_config, - bootstrap: RuntimeBuilder::new(client_config), - } - } - - pub async fn build(self) -> Result { - let setup = self.bootstrap.build().await?; - Ok(CliApp::from_runtime_setup(setup, self.cli_config)) - } -} - -impl CliApp { - pub fn builder( - client_config: ClientConfig, - cli_config: crate::config::CliConfig, - ) -> CliAppBuilder { - CliAppBuilder::new(client_config, cli_config) - } - - fn from_runtime_setup(setup: RuntimeSetup, cli_config: crate::config::CliConfig) -> Self { - let RuntimeSetup { - config: client_config, - oracles, - runtime, - } = setup; - - Self { - client_config, - cli_config, - oracles, - runtime, - } - } - - pub async fn execute(self) -> Result<()> { - tracing::info!("CLI client starting..."); - - // Setup CLI-specific provider (interactive input) - let (tx_action, rx_action) = - mpsc::channel::(self.client_config.channels.action_buffer); - - let handle = self.runtime.handle(); - let cli_kind = ProviderKind::Interactive(InteractiveKind::CliInput); - - // Register CLI input provider for player - handle.register_provider(cli_kind, CliActionProvider::new(rx_action))?; - - // Bind player to CLI input - handle.bind_entity_provider(EntityId::PLAYER, cli_kind)?; - - // Note: AI providers and default are already set up in RuntimeBuilder - // NPCs will use the AggressiveAiProvider configured in bootstrap - - let CliApp { - client_config, - cli_config, - oracles, - mut runtime, - } = self; - - // Subscribe to topics that CLI needs (GameState and Proof) - let handle = runtime.handle(); - let subscriptions = handle.subscribe_multiple(&[Topic::GameState, Topic::Proof]); - let initial_state = handle.query_state().await?; - - let mut messages = MessageLog::new(client_config.messages.capacity); - messages.push_text(format!( - "[{}] Welcome to the dungeon.", - initial_state.turn.clock - )); - - let consumer = - CliEventConsumer::new(messages, client_config.messages.effect_visibility.clone()); - - let event_loop = EventLoop::new( - handle.clone(), - subscriptions, - tx_action, - initial_state.entities.player().id, - consumer, - &initial_state, - oracles.clone(), - None, // Use default targeting strategy (ThreatBased) - cli_config, - ); - - // Start runtime.run() BEFORE terminal init to avoid deadlock - // EventLoop is already prepared to receive events, but terminal isn't initialized yet - let runtime_task = tokio::spawn(async move { - if let Err(e) = runtime.run().await { - tracing::error!("Runtime error: {}", e); - } - }); - - // Initialize terminal AFTER runtime starts so EventLoop can consume events immediately - let mut terminal = terminal::init()?; - let _guard = terminal::TerminalGuard; - - let _consumer = event_loop.run(&mut terminal).await?; - - runtime_task.abort(); - let _ = runtime_task.await; - - terminal::restore()?; - tracing::info!("CLI client exiting"); - - Ok(()) - } -} - -#[async_trait] -impl FrontendApp for CliApp { - async fn run(self) -> Result<()> { - self.execute().await - } -} diff --git a/crates/client/cli/src/event/handlers/input.rs b/crates/client/cli/src/event/handlers/input.rs deleted file mode 100644 index 98ebaab..0000000 --- a/crates/client/cli/src/event/handlers/input.rs +++ /dev/null @@ -1,203 +0,0 @@ -//! Input handling (keyboard and directional input). - -use anyhow::Result; -use client_core::EventConsumer; -use crossterm::event::{self as term_event, Event as TermEvent, KeyEvent, KeyEventKind}; -use game_core::{Action, EntityId, env::MapOracle}; -use tokio::time::Duration; - -use super::super::EventLoop; -use crate::{ - cursor::CursorMovement, - input::KeyAction, - presentation::terminal::Tui, - state::{AppMode, TargetingInputMode}, -}; - -impl EventLoop -where - C: EventConsumer, -{ - /// Poll for keyboard input and handle UI interactions. - pub(in crate::event) async fn handle_input_tick(&mut self, terminal: &mut Tui) -> Result { - if !term_event::poll(Duration::from_millis(0))? { - return Ok(false); - } - - match term_event::read()? { - TermEvent::Key(key) if key.kind == KeyEventKind::Press => { - self.handle_key_press(key, terminal).await - } - TermEvent::Resize(_, _) => { - self.render(terminal)?; - Ok(false) - } - _ => Ok(false), - } - } - - /// Handle key press and dispatch to appropriate handler. - pub(in crate::event) async fn handle_key_press( - &mut self, - key: KeyEvent, - terminal: &mut Tui, - ) -> Result { - match self.input.handle_key(key, &self.app_state.mode) { - KeyAction::Quit => { - self.consumer - .message_log_mut() - .push_text(format!("[{}] Quitting...", self.view_model.turn.clock)); - - // Just render the quit message - self.render(terminal)?; - Ok(true) - } - KeyAction::Submit(action) => { - if self.tx_action.send(action).await.is_err() { - tracing::error!("Action channel closed"); - return Ok(true); - } - Ok(false) - } - KeyAction::ToggleExamine => { - let cursor_pos = if let Some(entity_id) = self.app_state.highlighted_entity { - // Place cursor at highlighted entity's position - self.view_model - .actors - .iter() - .find(|a| a.id == entity_id) - .and_then(|a| a.position) - .or(self.view_model.player.position) - .unwrap_or_else(|| game_core::Position::new(0, 0)) - } else { - // No highlighted entity - default to player - self.view_model - .player - .position - .unwrap_or_else(|| game_core::Position::new(0, 0)) - }; - - self.app_state.toggle_examine(cursor_pos); - self.render(terminal)?; - Ok(false) - } - KeyAction::ExitModal => { - self.app_state.exit_to_normal(); - self.compute_auto_target(); - self.render(terminal)?; - Ok(false) - } - KeyAction::MoveCursor(direction) => { - // Check if in SelectDirection targeting mode - if let AppMode::Targeting(targeting_state) = &mut self.app_state.mode - && let TargetingInputMode::Direction { selected } = - &mut targeting_state.input_mode - { - // Update selected direction - *selected = Some(direction); - self.render(terminal)?; - return Ok(false); - } - - // Normal cursor movement (ExamineManual mode or SelectPosition targeting) - if let Some(cursor) = &mut self.app_state.manual_cursor { - let (dx, dy) = direction.to_delta(); - let dimensions = self.oracles.map.dimensions(); - cursor.move_by(dx, dy, dimensions.width, dimensions.height); - - // Update highlighted entity to first entity at new cursor position - self.update_highlighted_at_cursor(); - self.render(terminal)?; - } - Ok(false) - } - KeyAction::NextEntity => { - if self.app_state.mode == AppMode::Normal { - // Normal mode: cycle through all NPCs - self.cycle_highlighted_entity(1); - } else { - // Manual mode: cycle through entities at cursor position - self.cycle_entities_at_cursor(1); - } - self.render(terminal)?; - Ok(false) - } - KeyAction::PrevEntity => { - if self.app_state.mode == AppMode::Normal { - // Normal mode: cycle through all NPCs (backwards) - self.cycle_highlighted_entity(-1); - } else { - // Manual mode: cycle through entities at cursor position (backwards) - self.cycle_entities_at_cursor(-1); - } - self.render(terminal)?; - Ok(false) - } - KeyAction::DirectionalInput(direction) => { - self.handle_directional_input(direction).await?; - Ok(false) - } - KeyAction::UseSlot(slot) => { - self.handle_use_slot(slot).await?; - self.render(terminal)?; - Ok(false) - } - KeyAction::OpenAbilityMenu => { - self.handle_open_ability_menu().await?; - self.render(terminal)?; - Ok(false) - } - KeyAction::SelectAbilityForSlot(ability_idx) => { - self.handle_select_ability(ability_idx)?; - self.render(terminal)?; - Ok(false) - } - KeyAction::ConfirmTarget => { - self.handle_confirm_target().await?; - self.render(terminal)?; - Ok(false) - } - KeyAction::None => Ok(false), - } - } - - /// Handle directional input: Bump-to-attack or Move. - pub(in crate::event) async fn handle_directional_input( - &mut self, - direction: game_core::CardinalDirection, - ) -> Result<()> { - use game_core::{ActionInput, ActionKind, CharacterAction}; - - let Some(player_pos) = self.view_model.player.position else { - return Ok(()); - }; - let (dx, dy) = direction.offset(); - let target_pos = game_core::Position::new(player_pos.x + dx, player_pos.y + dy); - - // Check if there's an enemy at target position - let enemy_at_target = self.view_model.actors.iter().find(|actor| { - actor.id != EntityId::PLAYER - && actor.position == Some(target_pos) - && actor.stats.resource_current.hp > 0 - }); - - let action = if let Some(enemy) = enemy_at_target { - // Bump-to-attack: Attack the enemy - CharacterAction::new( - EntityId::PLAYER, - ActionKind::MeleeAttack, - ActionInput::Entity(enemy.id), - ) - } else { - // No enemy: Just move - CharacterAction::new( - EntityId::PLAYER, - ActionKind::Move, - ActionInput::Direction(direction), - ) - }; - - self.tx_action.send(Action::Character(action)).await?; - Ok(()) - } -} diff --git a/crates/client/cli/src/presentation/ui.rs b/crates/client/cli/src/presentation/ui.rs deleted file mode 100644 index a4af297..0000000 --- a/crates/client/cli/src/presentation/ui.rs +++ /dev/null @@ -1,118 +0,0 @@ -//! UI rendering using new widget architecture with ViewModel. -//! -//! This module provides the main render entry point that composes all widgets -//! to create the complete terminal UI. -use anyhow::Result; -use game_core::env::MapOracle; -use ratatui::layout::{Constraint, Direction, Layout}; - -use crate::{ - presentation::{terminal::Tui, theme::RatatuiTheme, widgets}, - state::{ActionSlots, AppMode, AppState}, -}; -use client_core::{message::MessageLog, view_model::ViewModel}; - -/// Rendering context containing all state and configuration needed for UI rendering. -pub struct RenderContext<'a> { - pub view_model: &'a ViewModel, - pub messages: &'a MessageLog, - pub app_state: &'a AppState, - pub action_slots: &'a ActionSlots, - pub available_actions: &'a [game_core::ActionKind], - pub message_panel_height: u16, - pub map: &'a dyn MapOracle, -} - -/// Render the terminal UI using ViewModel and widget system. -/// -/// This function composes all widgets to create the complete UI: -/// - Header: turn clock, current actor, mode indicator -/// - Game area: map (60%), player stats (20%), examine panel (20%) -/// - Messages: recent message log -/// - Action slots: hotkey display (1-9) -/// - Footer: context-sensitive key bindings -/// - Overlays: ability menu, targeting (modal) -/// -/// All widgets consume ViewModel directly with no adapter layers. -pub fn render_with_view_model(terminal: &mut Tui, ctx: &RenderContext) -> Result<()> { - let theme = RatatuiTheme; - - terminal.draw(|frame| { - let chunks = Layout::default() - .direction(Direction::Vertical) - .constraints([ - Constraint::Length(3), // Header - Constraint::Min(0), // Game area - Constraint::Length(ctx.message_panel_height), // Messages - Constraint::Length(3), // Action slots - Constraint::Length(2), // Footer - ]) - .split(frame.area()); - - widgets::header::render(frame, chunks[0], ctx.view_model, ctx.app_state); - - widgets::game_area::render( - frame, - chunks[1], - ctx.view_model, - ctx.app_state, - ctx.map, - &theme, - ); - - let recent_messages: Vec<_> = ctx - .messages - .recent(ctx.message_panel_height as usize) - .cloned() - .collect(); - widgets::messages::render( - frame, - chunks[2], - &recent_messages, - ctx.message_panel_height, - &theme, - ); - - // Action slots bar - widgets::action_slots::render(frame, chunks[3], ctx.action_slots); - - widgets::footer::render(frame, chunks[4], ctx.app_state); - - // Modal overlays (rendered on top) - if ctx.app_state.mode == AppMode::AbilityMenu { - // Center the ability menu - let area = centered_rect(60, 80, frame.area()); - widgets::ability_menu::render(frame, area, ctx.available_actions, ctx.action_slots); - } - // Targeting mode now uses in-game cursor visualization instead of overlay - })?; - - Ok(()) -} - -/// Create a centered rectangle for modal overlays. -fn centered_rect( - percent_x: u16, - percent_y: u16, - r: ratatui::layout::Rect, -) -> ratatui::layout::Rect { - use ratatui::layout::{Constraint, Direction, Layout}; - - let popup_layout = Layout::default() - .direction(Direction::Vertical) - .constraints([ - Constraint::Percentage((100 - percent_y) / 2), - Constraint::Percentage(percent_y), - Constraint::Percentage((100 - percent_y) / 2), - ]) - .split(r); - - Layout::default() - .direction(Direction::Horizontal) - .constraints([ - Constraint::Percentage((100 - percent_x) / 2), - Constraint::Percentage(percent_x), - Constraint::Percentage((100 - percent_x) / 2), - ]) - .split(popup_layout[1])[1] -} diff --git a/crates/client/core/src/frontend.rs b/crates/client/core/src/frontend.rs deleted file mode 100644 index ade9eb2..0000000 --- a/crates/client/core/src/frontend.rs +++ /dev/null @@ -1,10 +0,0 @@ -//! Trait describing a runnable client front-end. -use anyhow::Result; -use async_trait::async_trait; - -#[async_trait] -pub trait FrontendApp: Send { - async fn run(self) -> Result<()> - where - Self: Sized; -} diff --git a/crates/client/frontend/bevy/Cargo.toml b/crates/client/frontend/bevy/Cargo.toml new file mode 100644 index 0000000..b79d693 --- /dev/null +++ b/crates/client/frontend/bevy/Cargo.toml @@ -0,0 +1,51 @@ +[package] +name = "client-frontend-bevy" +version = "0.1.0" +edition = "2024" + +[features] +default = [] +risc0 = ["client-bootstrap/risc0"] +stub = ["client-bootstrap/stub"] +sp1 = ["client-bootstrap/sp1"] +arkworks = ["client-bootstrap/arkworks"] + +# Blockchain integration +sui = ["dep:client-blockchain-sui", "runtime/sui"] + +[dependencies] +# Core dependencies +game-core = { workspace = true } +runtime = { workspace = true } +client-frontend-core = { workspace = true } +client-bootstrap = { workspace = true } + +# Bevy engine +bevy = { workspace = true, features = [ + "bevy_asset", + "bevy_color", + "bevy_core_pipeline", + "bevy_render", + "bevy_sprite", + "bevy_text", + "bevy_ui", + "bevy_winit", + "default_font", + "multi_threaded", + "png", + "x11", +] } + +# Async runtime +tokio = { workspace = true } +async-trait = { workspace = true } + +# Error handling +anyhow = { workspace = true } +thiserror = { workspace = true } + +# Logging +tracing = { workspace = true } + +# Optional blockchain dependencies +client-blockchain-sui = { workspace = true, optional = true } diff --git a/crates/client/frontend/bevy/src/app.rs b/crates/client/frontend/bevy/src/app.rs new file mode 100644 index 0000000..428f3b3 --- /dev/null +++ b/crates/client/frontend/bevy/src/app.rs @@ -0,0 +1,135 @@ +//! Bevy frontend implementation. +//! +//! Pure UI layer that communicates with the game via RuntimeHandle only. + +use anyhow::Result; +use async_trait::async_trait; +use bevy::asset::AssetPlugin; +use bevy::prelude::*; +use client_bootstrap::oracles::OracleBundle; +use client_frontend_core::view_model::ViewModel; +use client_frontend_core::{FrontendConfig, MessageLog}; +use game_core::{Action, EntityId}; +use runtime::{InteractiveKind, ProviderKind, RuntimeHandle, Topic}; +use std::sync::Arc; +use tokio::sync::mpsc; + +use crate::context_menu::ContextMenuPlugin; +use crate::cursor::CursorPlugin; +use crate::events::{RuntimeEventReceivers, RuntimeEventsPlugin}; +use crate::input::InputPlugin; +use crate::provider::BevyActionProvider; +use crate::rendering::RenderingPlugin; +use crate::resources::*; +use crate::ui::UiPlugin; + +/// Bevy frontend (pure UI layer). +/// +/// This struct handles: +/// - 2D tile-based rendering +/// - User input collection +/// - Event consumption from runtime +/// - Action submission to runtime +/// +/// All communication with the game happens via RuntimeHandle. +pub struct BevyFrontend { + config: FrontendConfig, + oracles: OracleBundle, +} + +impl BevyFrontend { + /// Create a new Bevy frontend. + pub fn new(config: FrontendConfig, oracles: OracleBundle) -> Self { + Self { config, oracles } + } +} + +#[async_trait] +impl client_frontend_core::Frontend for BevyFrontend { + async fn run(&mut self, handle: RuntimeHandle) -> Result<()> { + tracing::info!("Bevy frontend starting..."); + + // Setup action provider (interactive input) + let (tx_action, rx_action) = mpsc::channel::(self.config.channels.action_buffer); + + let bevy_kind = ProviderKind::Interactive(InteractiveKind::BevyInput); + + // Register Bevy input provider for player + handle.register_provider(bevy_kind, BevyActionProvider::new(rx_action))?; + + // Bind player to Bevy input + handle.bind_entity_provider(EntityId::PLAYER, bevy_kind)?; + + // Subscribe to events + let subscriptions = handle.subscribe_multiple(&[Topic::GameState, Topic::Proof]); + let initial_state = handle.query_state().await?; + + // Initialize message log + let mut messages = MessageLog::new(self.config.messages.capacity); + messages.push_text(format!( + "[{}] Welcome to the dungeon.", + initial_state.turn.clock + )); + + // Create initial view model + let view_model = ViewModel::from_initial_state(&initial_state, self.oracles.map.as_ref()); + + // Prepare resources + let game_view_model = GameViewModel(view_model); + let game_message_log = GameMessageLog(messages); + let action_sender = ActionSender(tx_action); + let runtime_handle = GameRuntimeHandle(handle.clone()); + let frontend_config = GameFrontendConfig(self.config.clone()); + let tile_size = TileSize(32.0); + let camera_config = CameraConfig::default(); + let oracle_bundle = crate::resources::OracleBundle(Arc::new(self.oracles.clone())); + let event_receivers = RuntimeEventReceivers { + receivers: subscriptions, + }; + + tracing::info!("Bevy app starting with {} actors", game_view_model.0.actors.len()); + + // Run Bevy app (blocks until window is closed) + // Note: Bevy's App::run() takes ownership and doesn't return + // We run it in a blocking context since Bevy needs the main thread + App::new() + .add_plugins( + DefaultPlugins + .set(WindowPlugin { + primary_window: Some(Window { + title: "Dungeon".to_string(), + resolution: (1280.0, 720.0).into(), + ..default() + }), + ..default() + }) + .set(AssetPlugin { + // Use workspace root assets directory (resolved at compile time) + file_path: concat!(env!("CARGO_MANIFEST_DIR"), "/../../../../assets").to_string(), + ..default() + }), + ) + // Insert resources + .insert_resource(game_view_model) + .insert_resource(game_message_log) + .insert_resource(action_sender) + .insert_resource(runtime_handle) + .insert_resource(frontend_config) + .insert_resource(tile_size) + .insert_resource(camera_config) + .insert_resource(oracle_bundle) + .insert_resource(event_receivers) + // Add plugins + .add_plugins(RenderingPlugin) + .add_plugins(UiPlugin) + .add_plugins(InputPlugin) + .add_plugins(CursorPlugin) + .add_plugins(ContextMenuPlugin) + .add_plugins(RuntimeEventsPlugin) + // Run + .run(); + + tracing::info!("Bevy frontend exiting"); + Ok(()) + } +} diff --git a/crates/client/frontend/bevy/src/assets.rs b/crates/client/frontend/bevy/src/assets.rs new file mode 100644 index 0000000..1b51ddf --- /dev/null +++ b/crates/client/frontend/bevy/src/assets.rs @@ -0,0 +1,134 @@ +//! Sprite asset loading and management. + +use bevy::prelude::*; +use game_core::env::TerrainKind; +use game_core::PropKind; + +/// Resource holding all loaded sprite handles. +#[derive(Resource)] +pub struct SpriteAssets { + // Terrain tiles + pub tile_floor: Handle, + pub tile_wall: Handle, + pub tile_void: Handle, + pub tile_water: Handle, + pub tile_custom: Handle, + + // Actors + pub actor_player: Handle, + pub actor_goblin: Handle, + pub actor_skeleton: Handle, + pub actor_slime: Handle, + + // Props + pub prop_door_closed: Handle, + pub prop_door_open: Handle, + pub prop_switch_off: Handle, + pub prop_switch_on: Handle, + pub prop_hazard: Handle, + + // Items + pub item_potion_health: Handle, + pub item_potion_mana: Handle, + pub item_sword: Handle, + pub item_shield: Handle, + pub item_key: Handle, + pub item_gold: Handle, +} + +impl SpriteAssets { + /// Load all sprite assets from the assets/sprites directory. + pub fn load(asset_server: &AssetServer) -> Self { + Self { + // Terrain tiles + tile_floor: asset_server.load("sprites/tile_floor.png"), + tile_wall: asset_server.load("sprites/tile_wall.png"), + tile_void: asset_server.load("sprites/tile_void.png"), + tile_water: asset_server.load("sprites/tile_water.png"), + tile_custom: asset_server.load("sprites/tile_custom.png"), + + // Actors + actor_player: asset_server.load("sprites/actor_player.png"), + actor_goblin: asset_server.load("sprites/actor_goblin.png"), + actor_skeleton: asset_server.load("sprites/actor_skeleton.png"), + actor_slime: asset_server.load("sprites/actor_slime.png"), + + // Props + prop_door_closed: asset_server.load("sprites/prop_door_closed.png"), + prop_door_open: asset_server.load("sprites/prop_door_open.png"), + prop_switch_off: asset_server.load("sprites/prop_switch_off.png"), + prop_switch_on: asset_server.load("sprites/prop_switch_on.png"), + prop_hazard: asset_server.load("sprites/prop_hazard.png"), + + // Items + item_potion_health: asset_server.load("sprites/item_potion_health.png"), + item_potion_mana: asset_server.load("sprites/item_potion_mana.png"), + item_sword: asset_server.load("sprites/item_sword.png"), + item_shield: asset_server.load("sprites/item_shield.png"), + item_key: asset_server.load("sprites/item_key.png"), + item_gold: asset_server.load("sprites/item_gold.png"), + } + } + + /// Get the sprite handle for a terrain type. + pub fn tile_sprite(&self, terrain: TerrainKind) -> Handle { + match terrain { + TerrainKind::Floor => self.tile_floor.clone(), + TerrainKind::Wall => self.tile_wall.clone(), + TerrainKind::Void => self.tile_void.clone(), + TerrainKind::Water => self.tile_water.clone(), + TerrainKind::Custom(_) => self.tile_custom.clone(), + } + } + + /// Get the sprite handle for a prop type. + pub fn prop_sprite(&self, kind: &PropKind, is_active: bool) -> Handle { + match kind { + PropKind::Door => { + if is_active { + self.prop_door_open.clone() + } else { + self.prop_door_closed.clone() + } + } + PropKind::Switch => { + if is_active { + self.prop_switch_on.clone() + } else { + self.prop_switch_off.clone() + } + } + PropKind::Hazard => self.prop_hazard.clone(), + PropKind::Other => self.prop_hazard.clone(), // Fallback + } + } + + /// Get the player sprite handle. + pub fn player_sprite(&self) -> Handle { + self.actor_player.clone() + } + + /// Get an NPC sprite handle (cycles through available enemy types based on entity ID). + pub fn npc_sprite(&self, entity_id: u32) -> Handle { + // Cycle through available enemy sprites for variety + match entity_id % 3 { + 0 => self.actor_goblin.clone(), + 1 => self.actor_skeleton.clone(), + _ => self.actor_slime.clone(), + } + } + + /// Get a default item sprite (gold coins for now). + pub fn item_sprite(&self, _handle: u32) -> Handle { + // TODO: Map item handles to specific sprites based on item type + // For now, return gold as a default + self.item_gold.clone() + } +} + +/// System to load sprite assets at startup. +pub fn load_sprite_assets(mut commands: Commands, asset_server: Res) { + let sprites = SpriteAssets::load(&asset_server); + commands.insert_resource(sprites); + tracing::info!("Sprite assets loaded"); +} diff --git a/crates/client/frontend/bevy/src/components.rs b/crates/client/frontend/bevy/src/components.rs new file mode 100644 index 0000000..ef9d78a --- /dev/null +++ b/crates/client/frontend/bevy/src/components.rs @@ -0,0 +1,76 @@ +//! Bevy ECS components for game entities. + +use bevy::prelude::*; +use game_core::{EntityId, Position}; + +/// Marker component for tile sprites. +/// Position is stored for potential future use (e.g., tile click detection). +#[derive(Component)] +#[allow(dead_code)] +pub struct Tile { + pub position: Position, +} + +/// Marker component for actor sprites (player and NPCs). +#[derive(Component)] +pub struct Actor { + pub entity_id: EntityId, +} + +/// Marker component for the player entity. +#[derive(Component)] +pub struct Player; + +/// Marker component for NPC entities. +#[derive(Component)] +pub struct Npc; + +/// Marker component for item sprites. +#[derive(Component)] +pub struct Item { + pub entity_id: EntityId, +} + +/// Marker component for prop sprites. +#[derive(Component)] +pub struct Prop { + pub entity_id: EntityId, +} + +/// Marker component for the main game camera. +#[derive(Component)] +pub struct MainCamera; + +/// Marker component for UI root. +#[derive(Component)] +pub struct UiRoot; + +/// Marker component for the stats panel. +#[derive(Component)] +pub struct StatsPanel; + +/// Marker component for the message log panel. +#[derive(Component)] +pub struct MessageLogPanel; + +/// Marker component for health text. +#[derive(Component)] +pub struct HealthText; + +/// Marker component for mana text. +#[derive(Component)] +pub struct ManaText; + +/// Marker component for turn text. +#[derive(Component)] +pub struct TurnText; + +/// Marker component for message entries. +#[derive(Component)] +pub struct MessageEntry { + pub index: usize, +} + +/// Marker component for help panel. +#[derive(Component)] +pub struct HelpPanel; diff --git a/crates/client/frontend/bevy/src/context_menu.rs b/crates/client/frontend/bevy/src/context_menu.rs new file mode 100644 index 0000000..5981392 --- /dev/null +++ b/crates/client/frontend/bevy/src/context_menu.rs @@ -0,0 +1,404 @@ +//! Context menu system for right-click interactions. +//! +//! Provides a context menu that appears when right-clicking on entities, +//! showing available actions like Attack, Pickup, Interact. + +use bevy::prelude::*; +use bevy::window::PrimaryWindow; +use game_core::{Action, ActionInput, ActionKind, CharacterAction, EntityId}; + +use crate::cursor::{HoverState, HoverTarget}; +use crate::resources::{ActionSender, GameViewModel}; + +/// Plugin for context menu system. +pub struct ContextMenuPlugin; + +impl Plugin for ContextMenuPlugin { + fn build(&self, app: &mut App) { + app.init_resource::() + .add_systems(Startup, spawn_context_menu) + .add_systems( + Update, + ( + handle_right_click, + update_context_menu_position, + handle_menu_buttons, + close_menu_on_click_outside, + ), + ); + } +} + +/// Current state of the context menu. +#[derive(Resource, Default)] +pub struct ContextMenuState { + /// Whether the menu is currently visible. + pub visible: bool, + /// The target entity for the context menu. + pub target: Option, + /// Screen position where menu should appear. + pub screen_position: Vec2, +} + +/// Target of the context menu. +#[derive(Clone, Debug)] +pub struct ContextMenuTarget { + pub entity_id: EntityId, + pub is_player: bool, + pub target_type: TargetType, +} + +/// Type of entity being targeted. +#[derive(Clone, Debug, PartialEq)] +pub enum TargetType { + Actor, + Item, + Prop, +} + +/// Available actions in the context menu. +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum MenuAction { + Attack, + Pickup, +} + +impl MenuAction { + fn label(&self) -> &'static str { + match self { + MenuAction::Attack => "Attack", + MenuAction::Pickup => "Pick Up", + } + } + + fn color(&self) -> Color { + match self { + MenuAction::Attack => Color::srgb(1.0, 0.4, 0.4), + MenuAction::Pickup => Color::srgb(0.4, 1.0, 0.4), + } + } +} + +/// Marker for the context menu root. +#[derive(Component)] +pub struct ContextMenuRoot; + +/// Marker for context menu buttons with their action. +#[derive(Component)] +pub struct ContextMenuButton(pub MenuAction); + +/// Marker for the context menu title text. +#[derive(Component)] +pub struct ContextMenuTitle; + +/// Spawn the context menu UI (initially hidden). +fn spawn_context_menu(mut commands: Commands) { + commands + .spawn(( + Node { + position_type: PositionType::Absolute, + left: Val::Px(0.0), + top: Val::Px(0.0), + min_width: Val::Px(120.0), + padding: UiRect::all(Val::Px(8.0)), + flex_direction: FlexDirection::Column, + row_gap: Val::Px(4.0), + ..default() + }, + BackgroundColor(Color::srgba(0.1, 0.1, 0.15, 0.95)), + BorderColor(Color::srgb(0.4, 0.4, 0.5)), + BorderRadius::all(Val::Px(4.0)), + Visibility::Hidden, + ContextMenuRoot, + // High z-index to appear above everything + ZIndex(100), + )) + .with_children(|menu| { + // Title + menu.spawn(( + Text::new("Actions"), + TextFont { + font_size: 14.0, + ..default() + }, + TextColor(Color::srgb(0.8, 0.8, 0.8)), + ContextMenuTitle, + )); + + // Separator + menu.spawn(Node { + height: Val::Px(1.0), + width: Val::Percent(100.0), + margin: UiRect::vertical(Val::Px(4.0)), + ..default() + }) + .insert(BackgroundColor(Color::srgb(0.3, 0.3, 0.4))); + + // Action buttons will be spawned dynamically + for action in [MenuAction::Attack, MenuAction::Pickup] { + spawn_menu_button(menu, action); + } + }); +} + +fn spawn_menu_button(parent: &mut ChildBuilder, action: MenuAction) { + parent + .spawn(( + Button, + Node { + padding: UiRect::new(Val::Px(8.0), Val::Px(8.0), Val::Px(4.0), Val::Px(4.0)), + justify_content: JustifyContent::FlexStart, + ..default() + }, + BackgroundColor(Color::srgba(0.2, 0.2, 0.25, 0.8)), + BorderRadius::all(Val::Px(2.0)), + ContextMenuButton(action), + Visibility::Hidden, // Will be shown based on available actions + )) + .with_children(|button| { + button.spawn(( + Text::new(action.label()), + TextFont { + font_size: 13.0, + ..default() + }, + TextColor(action.color()), + )); + }); +} + +/// Handle right-click to open context menu. +fn handle_right_click( + mouse: Res>, + windows: Query<&Window, With>, + hover_state: Res, + view_model: Option>, + mut menu_state: ResMut, +) { + // Close menu on left click anywhere + if mouse.just_pressed(MouseButton::Left) && menu_state.visible { + // Will be handled by close_menu_on_click_outside + return; + } + + if !mouse.just_pressed(MouseButton::Right) { + return; + } + + let Some(view_model) = view_model else { + return; + }; + + let Ok(window) = windows.get_single() else { + return; + }; + + let Some(cursor_pos) = window.cursor_position() else { + return; + }; + + // Check if we're hovering over something + let Some(ref target) = hover_state.target else { + // Close menu if right-clicking on nothing + menu_state.visible = false; + menu_state.target = None; + return; + }; + + // Don't show menu for player (can't attack yourself) + let (entity_id, is_player, target_type) = match target { + HoverTarget::Actor { id, is_player } => (*id, *is_player, TargetType::Actor), + HoverTarget::Item { id } => (*id, false, TargetType::Item), + HoverTarget::Prop { id } => (*id, false, TargetType::Prop), + }; + + // Check if target is within attack range for actors (info message only) + if target_type == TargetType::Actor + && !is_player + && view_model.0.player.position.is_some() + && hover_state.position.is_some() + { + let player_pos = view_model.0.player.position.unwrap(); + let hover_pos = hover_state.position.unwrap(); + let distance = player_pos.chebyshev_distance(hover_pos); + if distance > 1 { + tracing::info!("Target out of attack range"); + } + } + + menu_state.visible = true; + menu_state.target = Some(ContextMenuTarget { + entity_id, + is_player, + target_type, + }); + menu_state.screen_position = cursor_pos; +} + +/// Update context menu position and visibility. +fn update_context_menu_position( + menu_state: Res, + view_model: Option>, + mut menu_root: Query<(&mut Node, &mut Visibility), With>, + mut menu_buttons: Query<(&ContextMenuButton, &mut Visibility), Without>, +) { + let Ok((mut node, mut visibility)) = menu_root.get_single_mut() else { + return; + }; + + if !menu_state.visible { + *visibility = Visibility::Hidden; + // Also hide all buttons explicitly + for (_, mut btn_visibility) in menu_buttons.iter_mut() { + *btn_visibility = Visibility::Hidden; + } + return; + } + + *visibility = Visibility::Visible; + node.left = Val::Px(menu_state.screen_position.x); + node.top = Val::Px(menu_state.screen_position.y); + + // Update button visibility based on target type and game state + let Some(ref target) = menu_state.target else { + return; + }; + + let view_model = view_model.as_ref(); + let is_player_turn = view_model + .map(|vm| vm.0.turn.current_actor == EntityId::PLAYER) + .unwrap_or(false); + + // Get player position for range checks + let player_pos = view_model.and_then(|vm| vm.0.player.position); + + // Check attack range (melee = 1) + let in_attack_range = if let (Some(vm), Some(player_pos)) = (view_model, player_pos) { + vm.0.actors + .iter() + .find(|a| a.id == target.entity_id) + .and_then(|a| a.position) + .map(|pos| player_pos.chebyshev_distance(pos) <= 1) + .unwrap_or(false) + } else { + false + }; + + // Check pickup range (must be standing on item, range = 0) + let in_pickup_range = if let (Some(vm), Some(player_pos)) = (view_model, player_pos) { + vm.0.items + .iter() + .find(|i| i.id == target.entity_id) + .map(|i| i.position == player_pos) + .unwrap_or(false) + } else { + false + }; + + for (button, mut btn_visibility) in menu_buttons.iter_mut() { + let should_show = match button.0 { + MenuAction::Attack => { + target.target_type == TargetType::Actor + && !target.is_player + && is_player_turn + && in_attack_range + } + MenuAction::Pickup => { + target.target_type == TargetType::Item && is_player_turn && in_pickup_range + } + }; + + *btn_visibility = if should_show { + Visibility::Visible + } else { + Visibility::Hidden + }; + } +} + +/// Handle clicks on menu buttons. +fn handle_menu_buttons( + mut interaction_query: Query< + (&Interaction, &ContextMenuButton, &mut BackgroundColor), + Changed, + >, + mut menu_state: ResMut, + action_sender: Option>, +) { + let Some(action_sender) = action_sender else { + return; + }; + + for (interaction, button, mut bg_color) in interaction_query.iter_mut() { + match *interaction { + Interaction::Pressed => { + let Some(ref target) = menu_state.target.clone() else { + continue; + }; + + // Execute the action based on button type + let action = match button.0 { + MenuAction::Attack => { + if target.target_type == TargetType::Actor && !target.is_player { + Some(Action::Character(CharacterAction::new( + EntityId::PLAYER, + ActionKind::MeleeAttack, + ActionInput::Target(target.entity_id), + ))) + } else { + None + } + } + MenuAction::Pickup => { + if target.target_type == TargetType::Item { + Some(Action::Character(CharacterAction::new( + EntityId::PLAYER, + ActionKind::PickupItem, + ActionInput::Target(target.entity_id), + ))) + } else { + None + } + } + }; + + if let Some(action) = action { + if let Err(e) = action_sender.0.try_send(action) { + tracing::warn!("Failed to send action: {}", e); + } + } + + // Always close menu after clicking a button + menu_state.visible = false; + menu_state.target = None; + } + Interaction::Hovered => { + *bg_color = BackgroundColor(Color::srgba(0.3, 0.3, 0.35, 0.9)); + } + Interaction::None => { + *bg_color = BackgroundColor(Color::srgba(0.2, 0.2, 0.25, 0.8)); + } + } + } +} + +/// Close menu when clicking outside. +fn close_menu_on_click_outside( + mouse: Res>, + mut menu_state: ResMut, + interaction_query: Query<&Interaction, With>, +) { + if !mouse.just_pressed(MouseButton::Left) || !menu_state.visible { + return; + } + + // Check if any button is being interacted with + let clicking_button = interaction_query + .iter() + .any(|i| *i == Interaction::Pressed || *i == Interaction::Hovered); + + if !clicking_button { + menu_state.visible = false; + menu_state.target = None; + } +} diff --git a/crates/client/frontend/bevy/src/cursor.rs b/crates/client/frontend/bevy/src/cursor.rs new file mode 100644 index 0000000..cf79cd5 --- /dev/null +++ b/crates/client/frontend/bevy/src/cursor.rs @@ -0,0 +1,152 @@ +//! Cursor and hover systems for tile examination. +//! +//! Provides mouse hover detection for examining tiles/entities. +//! Attack targeting is handled via context menu (right-click). + +use bevy::prelude::*; +use bevy::window::PrimaryWindow; +use game_core::Position; + +use crate::components::MainCamera; +use crate::resources::{GameViewModel, TileSize}; + +/// Plugin for hover systems. +pub struct CursorPlugin; + +impl Plugin for CursorPlugin { + fn build(&self, app: &mut App) { + app.init_resource::() + .add_systems(Update, update_hover_position); + } +} + +/// Mouse hover state for tile/entity inspection. +#[derive(Resource, Default)] +pub struct HoverState { + /// Current hovered grid position (if any). + pub position: Option, + /// What entity is being hovered (if any). + pub target: Option, +} + +/// What the mouse is hovering over. +#[derive(Clone, Debug)] +pub enum HoverTarget { + Actor { + id: game_core::EntityId, + is_player: bool, + }, + Item { + id: game_core::EntityId, + }, + Prop { + id: game_core::EntityId, + }, +} + +impl HoverState { + /// Update hover state from view model based on current position. + pub fn update_target(&mut self, view_model: &client_frontend_core::view_model::ViewModel) { + let Some(pos) = self.position else { + self.target = None; + return; + }; + + // Check actors first + for actor in &view_model.actors { + if actor.position == Some(pos) { + self.target = Some(HoverTarget::Actor { + id: actor.id, + is_player: actor.is_player, + }); + return; + } + } + + // Check items + for item in &view_model.items { + if item.position == pos { + self.target = Some(HoverTarget::Item { id: item.id }); + return; + } + } + + // Check props + for prop in &view_model.props { + if prop.position == pos { + self.target = Some(HoverTarget::Prop { id: prop.id }); + return; + } + } + + self.target = None; + } +} + +/// Update hover position from mouse cursor. +fn update_hover_position( + windows: Query<&Window, With>, + camera_query: Query<(&Camera, &GlobalTransform), With>, + view_model: Option>, + tile_size: Res, + mut hover_state: ResMut, +) { + let Some(view_model) = view_model else { + hover_state.position = None; + hover_state.target = None; + return; + }; + + let Ok(window) = windows.get_single() else { + return; + }; + + let Ok((camera, camera_transform)) = camera_query.get_single() else { + return; + }; + + let Some(cursor_position) = window.cursor_position() else { + hover_state.position = None; + hover_state.target = None; + return; + }; + + // Convert screen position to world position + let Ok(world_pos) = camera.viewport_to_world_2d(camera_transform, cursor_position) else { + hover_state.position = None; + hover_state.target = None; + return; + }; + + let map = &view_model.0.map; + let tile_px = tile_size.0; + + // Calculate map offset (same as tile rendering) + let map_width_px = map.width as f32 * tile_px; + let map_height_px = map.height as f32 * tile_px; + let offset_x = -map_width_px / 2.0; + let offset_y = -map_height_px / 2.0; + + // Convert world position to grid coordinates + let grid_x = ((world_pos.x - offset_x) / tile_px).floor() as i32; + let grid_y = ((world_pos.y - offset_y) / tile_px).floor() as i32; + + // Check bounds + if grid_x >= 0 && grid_x < map.width as i32 && grid_y >= 0 && grid_y < map.height as i32 { + let new_pos = Position::new(grid_x, grid_y); + let position_changed = hover_state.position != Some(new_pos); + + // Update position + if position_changed { + hover_state.position = Some(new_pos); + } + + // Update target if position changed OR game state changed (actors moved, etc.) + if position_changed || view_model.is_changed() { + hover_state.update_target(&view_model.0); + } + } else { + hover_state.position = None; + hover_state.target = None; + } +} diff --git a/crates/client/frontend/bevy/src/events.rs b/crates/client/frontend/bevy/src/events.rs new file mode 100644 index 0000000..05a981d --- /dev/null +++ b/crates/client/frontend/bevy/src/events.rs @@ -0,0 +1,119 @@ +//! Runtime event integration for Bevy. +//! +//! This module provides systems for receiving events from the runtime +//! and updating the Bevy game state accordingly. + +use bevy::prelude::*; +use client_frontend_core::{MessageLog, ViewModelUpdater}; +use runtime::events::{Event, GameStateEvent, Topic}; +use std::collections::HashMap; +use tokio::sync::broadcast; + +use crate::resources::{GameMessageLog, GameViewModel, OracleBundle, ViewModelDirty}; + +/// Resource holding event receivers from the runtime. +#[derive(Resource)] +pub struct RuntimeEventReceivers { + pub receivers: HashMap>, +} + +/// Plugin for runtime event integration. +pub struct RuntimeEventsPlugin; + +impl Plugin for RuntimeEventsPlugin { + fn build(&self, app: &mut App) { + app.insert_resource(ViewModelDirty::default()) + .add_systems(Update, poll_runtime_events); + } +} + +/// Poll runtime events and update game state. +/// +/// This system runs every frame and checks for new events from the runtime. +/// When events are received, it updates the ViewModel and marks it as dirty +/// for re-rendering. +fn poll_runtime_events( + mut receivers: Option>, + mut view_model: Option>, + mut message_log: Option>, + oracles: Option>, + mut dirty: ResMut, +) { + let Some(ref mut receivers) = receivers else { + return; + }; + let Some(ref mut view_model) = view_model else { + return; + }; + let Some(ref oracles) = oracles else { + return; + }; + + // Poll game state events + if let Some(rx) = receivers.receivers.get_mut(&Topic::GameState) { + // Process all available events + loop { + match rx.try_recv() { + Ok(event) => { + // Update view model + let _scope = ViewModelUpdater::update( + &mut view_model.0, + &event, + oracles.0.map.as_ref(), + ); + + // Log messages for significant events + if let Some(ref mut log) = message_log { + log_event(&event, &mut log.0); + } + + dirty.0 = true; + } + Err(broadcast::error::TryRecvError::Empty) => break, + Err(broadcast::error::TryRecvError::Lagged(n)) => { + tracing::warn!("Lagged {} events", n); + break; + } + Err(broadcast::error::TryRecvError::Closed) => { + tracing::error!("Runtime event channel closed"); + break; + } + } + } + } +} + +/// Log an event to the message log. +fn log_event(event: &Event, log: &mut MessageLog) { + match event { + Event::GameState(GameStateEvent::ActionExecuted { + action, + action_result, + .. + }) => { + // Format action for display + let msg = format!("Action executed: {:?}", action); + log.push_text(msg); + + // Log combat results if any + if action_result.summary.total_damage > 0 { + log.push_text(format!("Dealt {} damage", action_result.summary.total_damage)); + } + } + Event::GameState(GameStateEvent::ActionFailed { action, error, .. }) => { + log.push_text(format!("Action failed: {:?} - {}", action, error)); + } + Event::GameState(GameStateEvent::StateRestored { + from_nonce, + to_nonce, + }) => { + log.push_text(format!("State restored: {} -> {}", from_nonce, to_nonce)); + } + Event::Proof(_) => { + // Proof events are not logged to the message log + } + Event::ActionRef(_) => { + // Action refs are not logged (they're just references) + } + } +} diff --git a/crates/client/frontend/bevy/src/input.rs b/crates/client/frontend/bevy/src/input.rs new file mode 100644 index 0000000..902a69d --- /dev/null +++ b/crates/client/frontend/bevy/src/input.rs @@ -0,0 +1,121 @@ +//! Input handling systems for player controls. +//! +//! Keyboard controls for movement, pickup, and wait actions. +//! Attack is handled via context menu (right-click). + +use bevy::prelude::*; +use game_core::{Action, ActionInput, ActionKind, CardinalDirection, CharacterAction, EntityId}; + +use crate::context_menu::ContextMenuState; +use crate::resources::{ActionSender, GameViewModel}; + +/// Plugin for input handling systems. +pub struct InputPlugin; + +impl Plugin for InputPlugin { + fn build(&self, app: &mut App) { + app.init_resource::() + .add_systems(Update, (handle_keyboard_input, toggle_help)); + } +} + +/// Whether to show the help overlay. +#[derive(Resource, Default)] +pub struct ShowHelp(pub bool); + +/// Handle keyboard input and send actions to the runtime. +fn handle_keyboard_input( + keys: Res>, + action_sender: Option>, + view_model: Option>, + context_menu: Res, +) { + // Don't process keyboard input when context menu is open + if context_menu.visible { + return; + } + + let Some(action_sender) = action_sender else { + return; + }; + + let Some(view_model) = view_model else { + return; + }; + + // Check if it's the player's turn + if view_model.0.turn.current_actor != EntityId::PLAYER { + return; + } + + // Pickup item at current position with G + if keys.just_pressed(KeyCode::KeyG) { + // Find item at player's position + if let Some(player_pos) = view_model.0.player.position { + if let Some(item) = view_model.0.items.iter().find(|i| i.position == player_pos) { + let action = Action::Character(CharacterAction::new( + EntityId::PLAYER, + ActionKind::PickupItem, + ActionInput::Target(item.id), + )); + + if let Err(e) = action_sender.0.try_send(action) { + tracing::warn!("Failed to send pickup action: {}", e); + } + } else { + tracing::info!("No item at current position to pick up"); + } + } + return; + } + + // Movement with arrow keys + if let Some(dir) = get_direction(&keys) { + let action = Action::Character(CharacterAction::new( + EntityId::PLAYER, + ActionKind::Move, + ActionInput::Direction(dir), + )); + + if let Err(e) = action_sender.0.try_send(action) { + tracing::warn!("Failed to send action: {}", e); + } + } + + // Wait action with period or space + if keys.just_pressed(KeyCode::Period) || keys.just_pressed(KeyCode::Space) { + let action = Action::Character(CharacterAction::new( + EntityId::PLAYER, + ActionKind::Wait, + ActionInput::None, + )); + + if let Err(e) = action_sender.0.try_send(action) { + tracing::warn!("Failed to send wait action: {}", e); + } + } +} + +/// Toggle help overlay with H or F1. +fn toggle_help(keys: Res>, mut show_help: ResMut) { + if keys.just_pressed(KeyCode::KeyH) || keys.just_pressed(KeyCode::F1) { + show_help.0 = !show_help.0; + } +} + +/// Get direction from arrow keys. +fn get_direction(keys: &ButtonInput) -> Option { + if keys.just_pressed(KeyCode::ArrowUp) { + return Some(CardinalDirection::North); + } + if keys.just_pressed(KeyCode::ArrowDown) { + return Some(CardinalDirection::South); + } + if keys.just_pressed(KeyCode::ArrowRight) { + return Some(CardinalDirection::East); + } + if keys.just_pressed(KeyCode::ArrowLeft) { + return Some(CardinalDirection::West); + } + None +} diff --git a/crates/client/frontend/bevy/src/lib.rs b/crates/client/frontend/bevy/src/lib.rs new file mode 100644 index 0000000..39a2457 --- /dev/null +++ b/crates/client/frontend/bevy/src/lib.rs @@ -0,0 +1,23 @@ +//! Bevy-based graphical frontend for the dungeon game. +//! +//! This crate provides a 2D tile-based rendering frontend using the Bevy game engine. +//! It integrates with the runtime via `RuntimeHandle` and presents the game state +//! using the shared `ViewModel` from `client-frontend-core`. + +mod app; +mod assets; +mod components; +mod context_menu; +mod cursor; +mod events; +mod input; +mod provider; +mod rendering; +mod resources; +mod ui; + +pub use app::BevyFrontend; +pub use assets::SpriteAssets; +pub use context_menu::{ContextMenuPlugin, ContextMenuState}; +pub use cursor::{CursorPlugin, HoverState, HoverTarget}; +pub use provider::BevyActionProvider; diff --git a/crates/client/frontend/bevy/src/provider.rs b/crates/client/frontend/bevy/src/provider.rs new file mode 100644 index 0000000..3573490 --- /dev/null +++ b/crates/client/frontend/bevy/src/provider.rs @@ -0,0 +1,48 @@ +//! Action provider for Bevy frontend. + +use async_trait::async_trait; +use game_core::{Action, EntityId, GameEnv, GameState}; +use runtime::ActionProvider; +use tokio::sync::{Mutex, mpsc}; + +/// Action provider that waits for player input from Bevy UI. +pub struct BevyActionProvider { + /// Receiver for player actions from Bevy UI (wrapped in Mutex for interior mutability) + rx_action: Mutex>, +} + +impl BevyActionProvider { + pub fn new(rx_action: mpsc::Receiver) -> Self { + Self { + rx_action: Mutex::new(rx_action), + } + } +} + +#[async_trait] +impl ActionProvider for BevyActionProvider { + async fn provide_action( + &self, + entity: EntityId, + _state: &GameState, + _env: GameEnv<'_>, + ) -> runtime::Result { + let mut rx = self.rx_action.lock().await; + + match rx.recv().await { + Some(action) => { + // Validate that the action is for the correct entity + if action.actor() != entity { + tracing::error!( + "Action actor mismatch: received {:?}, expected {:?}", + action.actor(), + entity + ); + return Err(runtime::RuntimeError::InvalidEntityId(action.actor())); + } + Ok(action) + } + None => Err(runtime::RuntimeError::ActionProviderChannelClosed), + } + } +} diff --git a/crates/client/frontend/bevy/src/rendering/actors.rs b/crates/client/frontend/bevy/src/rendering/actors.rs new file mode 100644 index 0000000..f37cb69 --- /dev/null +++ b/crates/client/frontend/bevy/src/rendering/actors.rs @@ -0,0 +1,179 @@ +//! Actor (player and NPC) rendering systems. + +use bevy::prelude::*; + +use crate::assets::SpriteAssets; +use crate::components::{Actor, MainCamera, Npc, Player}; +use crate::resources::{CameraConfig, GameViewModel, TileSize}; + +/// Spawn actor sprites from the view model. +pub fn spawn_actors( + mut commands: Commands, + view_model: Option>, + tile_size: Res, + sprites: Option>, + existing_actors: Query>, + mut actors_spawned: Local, +) { + let Some(view_model) = view_model else { + return; + }; + + let Some(sprites) = sprites else { + return; + }; + + // Only spawn once initially (updates handled separately) + if *actors_spawned { + return; + } + + // Clear existing actors + for entity in existing_actors.iter() { + commands.entity(entity).despawn(); + } + + let tile_px = tile_size.0; + let map = &view_model.0.map; + + // Calculate offset (same as tiles) + let map_width = map.width as f32 * tile_px; + let map_height = map.height as f32 * tile_px; + let offset_x = -map_width / 2.0 + tile_px / 2.0; + let offset_y = -map_height / 2.0 + tile_px / 2.0; + + for actor in &view_model.0.actors { + let Some(pos) = actor.position else { + continue; + }; + + let world_x = pos.x as f32 * tile_px + offset_x; + let world_y = pos.y as f32 * tile_px + offset_y; + + // Get sprite texture based on actor type + let texture = if actor.is_player { + sprites.player_sprite() + } else { + sprites.npc_sprite(actor.id.0) + }; + + let mut entity_commands = commands.spawn(( + Sprite { + image: texture, + custom_size: Some(Vec2::splat(tile_px)), + ..default() + }, + Transform::from_xyz(world_x, world_y, 1.0), // Z = 1 to render above tiles + Actor { + entity_id: actor.id, + }, + )); + + if actor.is_player { + entity_commands.insert(Player); + } else { + entity_commands.insert(Npc); + } + } + + *actors_spawned = true; + tracing::info!("Spawned {} actors with sprites", view_model.0.actors.len()); +} + +/// Update actor positions when the view model changes. +/// Also despawns actors that were killed (no longer in view model). +pub fn update_actor_positions( + mut commands: Commands, + view_model: Option>, + tile_size: Res, + actors: Query<(Entity, &Actor, &Transform)>, +) { + let Some(view_model) = view_model else { + return; + }; + + if !view_model.is_changed() { + return; + } + + let tile_px = tile_size.0; + let map = &view_model.0.map; + + let map_width = map.width as f32 * tile_px; + let map_height = map.height as f32 * tile_px; + let offset_x = -map_width / 2.0 + tile_px / 2.0; + let offset_y = -map_height / 2.0 + tile_px / 2.0; + + for (entity, actor_component, transform) in actors.iter() { + // Find the actor in the view model + let actor_view = view_model + .0 + .actors + .iter() + .find(|a| a.id == actor_component.entity_id); + + match actor_view.and_then(|a| a.position) { + Some(pos) => { + let world_x = pos.x as f32 * tile_px + offset_x; + let world_y = pos.y as f32 * tile_px + offset_y; + + // Only update if position changed significantly + if (transform.translation.x - world_x).abs() > 0.01 + || (transform.translation.y - world_y).abs() > 0.01 + { + commands.entity(entity).insert(Transform::from_xyz( + world_x, + world_y, + transform.translation.z, + )); + } + } + None => { + // Actor was killed or has no position - despawn the entity + commands.entity(entity).despawn(); + } + } + } +} + +/// Update camera to follow the player. +pub fn update_camera_follow( + view_model: Option>, + tile_size: Res, + camera_config: Res, + mut camera: Query<&mut Transform, (With, Without)>, +) { + if !camera_config.follow_player { + return; + } + + let Some(view_model) = view_model else { + return; + }; + + let Some(player_pos) = view_model.0.player.position else { + return; + }; + + let Ok(mut camera_transform) = camera.get_single_mut() else { + return; + }; + + let tile_px = tile_size.0; + let map = &view_model.0.map; + + let map_width = map.width as f32 * tile_px; + let map_height = map.height as f32 * tile_px; + let offset_x = -map_width / 2.0 + tile_px / 2.0; + let offset_y = -map_height / 2.0 + tile_px / 2.0; + + let target_x = player_pos.x as f32 * tile_px + offset_x; + let target_y = player_pos.y as f32 * tile_px + offset_y; + + // Smooth camera follow + let lerp_factor = 0.1; + camera_transform.translation.x += + (target_x - camera_transform.translation.x) * lerp_factor; + camera_transform.translation.y += + (target_y - camera_transform.translation.y) * lerp_factor; +} diff --git a/crates/client/frontend/bevy/src/rendering/items.rs b/crates/client/frontend/bevy/src/rendering/items.rs new file mode 100644 index 0000000..1dd2ed2 --- /dev/null +++ b/crates/client/frontend/bevy/src/rendering/items.rs @@ -0,0 +1,124 @@ +//! Item rendering systems. + +use bevy::prelude::*; + +use crate::assets::SpriteAssets; +use crate::components::Item; +use crate::resources::{GameViewModel, TileSize}; + +/// Spawn item sprites from the view model. +pub fn spawn_items( + mut commands: Commands, + view_model: Option>, + tile_size: Res, + sprites: Option>, + existing_items: Query>, + mut items_spawned: Local, +) { + let Some(view_model) = view_model else { + return; + }; + + let Some(sprites) = sprites else { + return; + }; + + // Only spawn once initially (updates handled separately) + if *items_spawned { + return; + } + + // Clear existing items + for entity in existing_items.iter() { + commands.entity(entity).despawn(); + } + + let tile_px = tile_size.0; + let map = &view_model.0.map; + + // Calculate offset (same as tiles) + let map_width = map.width as f32 * tile_px; + let map_height = map.height as f32 * tile_px; + let offset_x = -map_width / 2.0 + tile_px / 2.0; + let offset_y = -map_height / 2.0 + tile_px / 2.0; + + for item in &view_model.0.items { + let world_x = item.position.x as f32 * tile_px + offset_x; + let world_y = item.position.y as f32 * tile_px + offset_y; + + // Get sprite texture based on item type + let texture = sprites.item_sprite(item.handle.0); + + // Items are slightly smaller than a tile + let item_size = tile_px * 0.75; + + commands.spawn(( + Sprite { + image: texture, + custom_size: Some(Vec2::splat(item_size)), + ..default() + }, + Transform::from_xyz(world_x, world_y, 0.3), // Z = 0.3 below props but above tiles + Item { + entity_id: item.id, + }, + )); + } + + *items_spawned = true; + if !view_model.0.items.is_empty() { + tracing::info!("Spawned {} items with sprites", view_model.0.items.len()); + } +} + +/// Update item positions when the view model changes. +/// Also despawns items that were picked up (no longer in view model). +pub fn update_item_positions( + mut commands: Commands, + view_model: Option>, + tile_size: Res, + items: Query<(Entity, &Item, &Transform)>, +) { + let Some(view_model) = view_model else { + return; + }; + + if !view_model.is_changed() { + return; + } + + let tile_px = tile_size.0; + let map = &view_model.0.map; + + let map_width = map.width as f32 * tile_px; + let map_height = map.height as f32 * tile_px; + let offset_x = -map_width / 2.0 + tile_px / 2.0; + let offset_y = -map_height / 2.0 + tile_px / 2.0; + + for (entity, item_component, transform) in items.iter() { + // Find the item in the view model + if let Some(item_view) = view_model + .0 + .items + .iter() + .find(|i| i.id == item_component.entity_id) + { + let world_x = item_view.position.x as f32 * tile_px + offset_x; + let world_y = item_view.position.y as f32 * tile_px + offset_y; + + // Only update if position changed + if (transform.translation.x - world_x).abs() > 0.01 + || (transform.translation.y - world_y).abs() > 0.01 + { + commands.entity(entity).insert(Transform::from_xyz( + world_x, + world_y, + transform.translation.z, + )); + } + } else { + // Item was picked up - despawn the entity + commands.entity(entity).despawn(); + } + } +} diff --git a/crates/client/frontend/bevy/src/rendering/mod.rs b/crates/client/frontend/bevy/src/rendering/mod.rs new file mode 100644 index 0000000..2c697e5 --- /dev/null +++ b/crates/client/frontend/bevy/src/rendering/mod.rs @@ -0,0 +1,44 @@ +//! Rendering systems for tiles, actors, and other game entities. + +mod actors; +mod items; +mod props; +mod tiles; + +pub use actors::*; +pub use items::*; +pub use props::*; +pub use tiles::*; + +use bevy::prelude::*; + +use crate::assets::load_sprite_assets; + +/// Plugin for game rendering systems. +pub struct RenderingPlugin; + +impl Plugin for RenderingPlugin { + fn build(&self, app: &mut App) { + app.add_systems(Startup, (load_sprite_assets, setup_camera).chain()) + .add_systems( + Update, + ( + spawn_tiles, + spawn_actors, + spawn_props, + spawn_items, + update_actor_positions, + update_prop_states, + update_item_positions, + update_camera_follow, + ) + .chain(), + ); + } +} + +fn setup_camera(mut commands: Commands) { + use crate::components::MainCamera; + + commands.spawn((Camera2d, MainCamera)); +} diff --git a/crates/client/frontend/bevy/src/rendering/props.rs b/crates/client/frontend/bevy/src/rendering/props.rs new file mode 100644 index 0000000..d90a011 --- /dev/null +++ b/crates/client/frontend/bevy/src/rendering/props.rs @@ -0,0 +1,106 @@ +//! Prop (doors, switches, hazards) rendering systems. + +use bevy::prelude::*; + +use crate::assets::SpriteAssets; +use crate::components::Prop; +use crate::resources::{GameViewModel, TileSize}; + +/// Spawn prop sprites from the view model. +pub fn spawn_props( + mut commands: Commands, + view_model: Option>, + tile_size: Res, + sprites: Option>, + existing_props: Query>, + mut props_spawned: Local, +) { + let Some(view_model) = view_model else { + return; + }; + + let Some(sprites) = sprites else { + return; + }; + + // Only spawn once initially (updates handled separately) + if *props_spawned { + return; + } + + // Clear existing props + for entity in existing_props.iter() { + commands.entity(entity).despawn(); + } + + let tile_px = tile_size.0; + let map = &view_model.0.map; + + // Calculate offset (same as tiles) + let map_width = map.width as f32 * tile_px; + let map_height = map.height as f32 * tile_px; + let offset_x = -map_width / 2.0 + tile_px / 2.0; + let offset_y = -map_height / 2.0 + tile_px / 2.0; + + for prop in &view_model.0.props { + let world_x = prop.position.x as f32 * tile_px + offset_x; + let world_y = prop.position.y as f32 * tile_px + offset_y; + + // Get sprite texture based on prop type and state + let texture = sprites.prop_sprite(&prop.kind, prop.is_active); + + commands.spawn(( + Sprite { + image: texture, + custom_size: Some(Vec2::splat(tile_px)), + ..default() + }, + Transform::from_xyz(world_x, world_y, 0.5), // Z = 0.5 between tiles and actors + Prop { + entity_id: prop.id, + }, + )); + } + + *props_spawned = true; + if !view_model.0.props.is_empty() { + tracing::info!("Spawned {} props with sprites", view_model.0.props.len()); + } +} + +/// Update prop sprites when their state changes. +/// Also despawns props that were destroyed (no longer in view model). +pub fn update_prop_states( + mut commands: Commands, + view_model: Option>, + sprites: Option>, + mut props: Query<(Entity, &Prop, &mut Sprite)>, +) { + let Some(view_model) = view_model else { + return; + }; + + let Some(sprites) = sprites else { + return; + }; + + if !view_model.is_changed() { + return; + } + + for (entity, prop_component, mut sprite) in props.iter_mut() { + // Find the prop in the view model + if let Some(prop_view) = view_model + .0 + .props + .iter() + .find(|p| p.id == prop_component.entity_id) + { + // Update sprite based on current state + sprite.image = sprites.prop_sprite(&prop_view.kind, prop_view.is_active); + } else { + // Prop was destroyed - despawn the entity + commands.entity(entity).despawn(); + } + } +} diff --git a/crates/client/frontend/bevy/src/rendering/tiles.rs b/crates/client/frontend/bevy/src/rendering/tiles.rs new file mode 100644 index 0000000..26883a0 --- /dev/null +++ b/crates/client/frontend/bevy/src/rendering/tiles.rs @@ -0,0 +1,70 @@ +//! Tile rendering systems. + +use bevy::prelude::*; + +use crate::assets::SpriteAssets; +use crate::components::Tile; +use crate::resources::{GameViewModel, TileSize}; + +/// Spawn tile sprites from the view model. +pub fn spawn_tiles( + mut commands: Commands, + view_model: Option>, + tile_size: Res, + sprites: Option>, + mut tiles_spawned: Local, + existing_tiles: Query>, +) { + let Some(view_model) = view_model else { + return; + }; + + let Some(sprites) = sprites else { + return; + }; + + // Only spawn once (tiles are static) + if *tiles_spawned { + return; + } + + // Clear any existing tiles + for entity in existing_tiles.iter() { + commands.entity(entity).despawn(); + } + + let map = &view_model.0.map; + let tile_px = tile_size.0; + + // Calculate offset to center the map + let map_width = map.width as f32 * tile_px; + let map_height = map.height as f32 * tile_px; + let offset_x = -map_width / 2.0 + tile_px / 2.0; + let offset_y = -map_height / 2.0 + tile_px / 2.0; + + for (row_idx, row) in map.tiles.iter().enumerate() { + for (col_idx, tile_view) in row.iter().enumerate() { + let texture = sprites.tile_sprite(tile_view.terrain); + + // Convert grid position to world position + // Note: tiles are stored in Y-reversed order (top row first) + let world_x = col_idx as f32 * tile_px + offset_x; + let world_y = (map.height as usize - 1 - row_idx) as f32 * tile_px + offset_y; + + commands.spawn(( + Sprite { + image: texture, + custom_size: Some(Vec2::splat(tile_px)), + ..default() + }, + Transform::from_xyz(world_x, world_y, 0.0), + Tile { + position: tile_view.position, + }, + )); + } + } + + *tiles_spawned = true; + tracing::info!("Spawned {} tiles with sprites", map.width * map.height); +} diff --git a/crates/client/frontend/bevy/src/resources.rs b/crates/client/frontend/bevy/src/resources.rs new file mode 100644 index 0000000..4ba5fec --- /dev/null +++ b/crates/client/frontend/bevy/src/resources.rs @@ -0,0 +1,69 @@ +//! Bevy resources for game state and runtime communication. + +use bevy::prelude::*; +use client_frontend_core::view_model::ViewModel; +use client_frontend_core::{MessageLog, FrontendConfig}; +use runtime::RuntimeHandle; +use std::sync::Arc; +use tokio::sync::mpsc; +use game_core::Action; + +/// Game view model resource, synchronized with runtime events. +#[derive(Resource)] +pub struct GameViewModel(pub ViewModel); + +/// Message log for displaying game events. +#[derive(Resource)] +pub struct GameMessageLog(pub MessageLog); + +/// Channel for sending player actions to the runtime. +#[derive(Resource)] +pub struct ActionSender(pub mpsc::Sender); + +/// Runtime handle for querying state and subscribing to events. +/// Reserved for future use (e.g., querying state mid-game). +#[derive(Resource)] +#[allow(dead_code)] +pub struct GameRuntimeHandle(pub RuntimeHandle); + +/// Frontend configuration. +/// Reserved for future use (e.g., configurable message limits). +#[derive(Resource)] +#[allow(dead_code)] +pub struct GameFrontendConfig(pub FrontendConfig); + +/// Tile size in pixels for rendering. +#[derive(Resource)] +pub struct TileSize(pub f32); + +impl Default for TileSize { + fn default() -> Self { + Self(32.0) + } +} + +/// Camera configuration. +/// Reserved for future use (e.g., zoom controls, camera following). +#[derive(Resource)] +#[allow(dead_code)] +pub struct CameraConfig { + pub zoom: f32, + pub follow_player: bool, +} + +impl Default for CameraConfig { + fn default() -> Self { + Self { + zoom: 1.0, + follow_player: true, + } + } +} + +/// Flag indicating the view model needs to be re-synced. +#[derive(Resource, Default)] +pub struct ViewModelDirty(pub bool); + +/// Oracle bundle for map lookups (wrapped in Arc for thread safety). +#[derive(Resource)] +pub struct OracleBundle(pub Arc); diff --git a/crates/client/frontend/bevy/src/ui/mod.rs b/crates/client/frontend/bevy/src/ui/mod.rs new file mode 100644 index 0000000..e724d75 --- /dev/null +++ b/crates/client/frontend/bevy/src/ui/mod.rs @@ -0,0 +1,23 @@ +//! UI systems for stats panel, message log, and other HUD elements. + +mod panels; +mod styles; + +pub use panels::*; + +use bevy::prelude::*; + +/// Plugin for UI systems. +pub struct UiPlugin; + +impl Plugin for UiPlugin { + fn build(&self, app: &mut App) { + app.add_systems(Startup, setup_ui) + .add_systems(Update, ( + update_stats_panel, + update_message_log, + update_help_visibility, + update_examine_panel, + )); + } +} diff --git a/crates/client/frontend/bevy/src/ui/panels.rs b/crates/client/frontend/bevy/src/ui/panels.rs new file mode 100644 index 0000000..a8529cc --- /dev/null +++ b/crates/client/frontend/bevy/src/ui/panels.rs @@ -0,0 +1,468 @@ +//! UI panel systems for stats, message log, and hover inspection. + +use bevy::prelude::*; +use game_core::env::MapOracle; + +use crate::components::{HealthText, HelpPanel, ManaText, MessageEntry, MessageLogPanel, StatsPanel, TurnText, UiRoot}; +use crate::cursor::{HoverState, HoverTarget}; +use crate::input::ShowHelp; +use crate::resources::{GameMessageLog, GameViewModel, OracleBundle}; +use super::styles::*; + +/// Marker component for examine panel (shown on mouse hover). +#[derive(Component)] +pub struct ExaminePanel; + +/// Marker component for examine panel text lines. +#[derive(Component)] +pub struct ExamineText { + pub line: usize, +} + +/// Setup the main UI layout. +pub fn setup_ui(mut commands: Commands) { + // Root UI container + commands + .spawn(( + Node { + width: Val::Percent(100.0), + height: Val::Percent(100.0), + flex_direction: FlexDirection::Row, + justify_content: JustifyContent::SpaceBetween, + ..default() + }, + UiRoot, + )) + .with_children(|parent| { + // Left panel: Stats + spawn_stats_panel(parent); + + // Center: Input mode indicator at top + spawn_center_ui(parent); + + // Right column: Message log and Examine panel + spawn_right_column(parent); + }); + + // Help panel overlay (hidden by default) + spawn_help_panel(&mut commands); +} + +fn spawn_stats_panel(parent: &mut ChildBuilder) { + parent + .spawn(( + Node { + width: Val::Px(200.0), + height: Val::Auto, + padding: UiRect::all(Val::Px(10.0)), + margin: UiRect::all(Val::Px(10.0)), + flex_direction: FlexDirection::Column, + row_gap: Val::Px(8.0), + align_self: AlignSelf::FlexStart, + ..default() + }, + BackgroundColor(PANEL_BG), + BorderColor(PANEL_BORDER), + StatsPanel, + )) + .with_children(|panel| { + // Title + panel.spawn(( + Text::new("Player Stats"), + text_style(HEADER_FONT_SIZE, TEXT_COLOR).0, + text_style(HEADER_FONT_SIZE, TEXT_COLOR).1, + )); + + // Health + panel.spawn(( + Text::new("HP: --/--"), + text_style(TEXT_FONT_SIZE, HEALTH_COLOR).0, + text_style(TEXT_FONT_SIZE, HEALTH_COLOR).1, + HealthText, + )); + + // Mana + panel.spawn(( + Text::new("MP: --/--"), + text_style(TEXT_FONT_SIZE, MANA_COLOR).0, + text_style(TEXT_FONT_SIZE, MANA_COLOR).1, + ManaText, + )); + + // Separator + panel.spawn(Node { + height: Val::Px(1.0), + width: Val::Percent(100.0), + margin: UiRect::vertical(Val::Px(5.0)), + ..default() + }); + + // Turn info + panel.spawn(( + Text::new("Turn: --"), + text_style(TEXT_FONT_SIZE, TURN_COLOR).0, + text_style(TEXT_FONT_SIZE, TURN_COLOR).1, + TurnText, + )); + + // Controls hint + panel.spawn(Node { + height: Val::Px(1.0), + width: Val::Percent(100.0), + margin: UiRect::vertical(Val::Px(5.0)), + ..default() + }); + + panel.spawn(( + Text::new("H - Help"), + text_style(SMALL_FONT_SIZE, TEXT_COLOR).0, + text_style(SMALL_FONT_SIZE, TEXT_COLOR).1, + )); + }); +} + +fn spawn_center_ui(parent: &mut ChildBuilder) { + // Center spacer to push right panel to the edge + parent.spawn(Node { + flex_grow: 1.0, + ..default() + }); +} + +fn spawn_right_column(parent: &mut ChildBuilder) { + parent + .spawn(Node { + flex_direction: FlexDirection::Column, + align_items: AlignItems::FlexEnd, + justify_content: JustifyContent::SpaceBetween, + height: Val::Percent(100.0), + ..default() + }) + .with_children(|column| { + // Top: Examine panel (shown on mouse hover) + spawn_examine_panel(column); + + // Bottom: Message log + spawn_message_log_panel(column); + }); +} + +fn spawn_examine_panel(parent: &mut ChildBuilder) { + parent + .spawn(( + Node { + width: Val::Px(250.0), + height: Val::Auto, + padding: UiRect::all(Val::Px(10.0)), + margin: UiRect::all(Val::Px(10.0)), + flex_direction: FlexDirection::Column, + row_gap: Val::Px(4.0), + ..default() + }, + BackgroundColor(Color::srgba(0.1, 0.1, 0.15, 0.9)), + BorderColor(Color::srgb(0.3, 0.5, 0.7)), + Visibility::Hidden, + ExaminePanel, + )) + .with_children(|panel| { + // Title + panel.spawn(( + Text::new("Inspect"), + text_style(HEADER_FONT_SIZE, Color::srgb(0.5, 0.8, 1.0)).0, + text_style(HEADER_FONT_SIZE, Color::srgb(0.5, 0.8, 1.0)).1, + )); + + // 6 lines for examine info + for i in 0..6 { + panel.spawn(( + Text::new(""), + text_style(SMALL_FONT_SIZE, TEXT_COLOR).0, + text_style(SMALL_FONT_SIZE, TEXT_COLOR).1, + ExamineText { line: i }, + )); + } + }); +} + +fn spawn_message_log_panel(parent: &mut ChildBuilder) { + parent + .spawn(( + Node { + width: Val::Px(300.0), + height: Val::Px(200.0), + padding: UiRect::all(Val::Px(10.0)), + margin: UiRect::all(Val::Px(10.0)), + flex_direction: FlexDirection::Column, + row_gap: Val::Px(4.0), + overflow: Overflow::clip(), + ..default() + }, + BackgroundColor(PANEL_BG), + BorderColor(PANEL_BORDER), + MessageLogPanel, + )) + .with_children(|panel| { + // Title + panel.spawn(( + Text::new("Messages"), + text_style(HEADER_FONT_SIZE, TEXT_COLOR).0, + text_style(HEADER_FONT_SIZE, TEXT_COLOR).1, + )); + + // Message entries will be spawned dynamically + for i in 0..8 { + panel.spawn(( + Text::new(""), + text_style(SMALL_FONT_SIZE, TEXT_COLOR).0, + text_style(SMALL_FONT_SIZE, TEXT_COLOR).1, + MessageEntry { index: i }, + )); + } + }); +} + +fn spawn_help_panel(commands: &mut Commands) { + commands + .spawn(( + Node { + position_type: PositionType::Absolute, + left: Val::Percent(50.0), + top: Val::Percent(50.0), + width: Val::Px(300.0), + padding: UiRect::all(Val::Px(20.0)), + flex_direction: FlexDirection::Column, + row_gap: Val::Px(8.0), + ..default() + }, + BackgroundColor(Color::srgba(0.1, 0.1, 0.15, 0.95)), + BorderColor(Color::srgb(0.4, 0.4, 0.5)), + Visibility::Hidden, + HelpPanel, + )) + .with_children(|panel| { + // Title + panel.spawn(( + Text::new("Controls"), + text_style(HEADER_FONT_SIZE, Color::srgb(1.0, 0.9, 0.3)).0, + text_style(HEADER_FONT_SIZE, Color::srgb(1.0, 0.9, 0.3)).1, + )); + + // Movement section + panel.spawn(( + Text::new("Movement"), + text_style(TEXT_FONT_SIZE, Color::srgb(0.7, 0.9, 1.0)).0, + text_style(TEXT_FONT_SIZE, Color::srgb(0.7, 0.9, 1.0)).1, + )); + panel.spawn(( + Text::new(" Arrow Keys - Move"), + text_style(SMALL_FONT_SIZE, TEXT_COLOR).0, + text_style(SMALL_FONT_SIZE, TEXT_COLOR).1, + )); + + // Actions section + panel.spawn(( + Text::new("Actions"), + text_style(TEXT_FONT_SIZE, Color::srgb(0.7, 0.9, 1.0)).0, + text_style(TEXT_FONT_SIZE, Color::srgb(0.7, 0.9, 1.0)).1, + )); + panel.spawn(( + Text::new(" G - Pickup item"), + text_style(SMALL_FONT_SIZE, TEXT_COLOR).0, + text_style(SMALL_FONT_SIZE, TEXT_COLOR).1, + )); + panel.spawn(( + Text::new(" Space/. - Wait"), + text_style(SMALL_FONT_SIZE, TEXT_COLOR).0, + text_style(SMALL_FONT_SIZE, TEXT_COLOR).1, + )); + + // Mouse section + panel.spawn(( + Text::new("Mouse"), + text_style(TEXT_FONT_SIZE, Color::srgb(0.7, 0.9, 1.0)).0, + text_style(TEXT_FONT_SIZE, Color::srgb(0.7, 0.9, 1.0)).1, + )); + panel.spawn(( + Text::new(" Hover - Inspect tile"), + text_style(SMALL_FONT_SIZE, TEXT_COLOR).0, + text_style(SMALL_FONT_SIZE, TEXT_COLOR).1, + )); + panel.spawn(( + Text::new(" Right-click - Actions menu"), + text_style(SMALL_FONT_SIZE, TEXT_COLOR).0, + text_style(SMALL_FONT_SIZE, TEXT_COLOR).1, + )); + + // Other section + panel.spawn(( + Text::new("Other"), + text_style(TEXT_FONT_SIZE, Color::srgb(0.7, 0.9, 1.0)).0, + text_style(TEXT_FONT_SIZE, Color::srgb(0.7, 0.9, 1.0)).1, + )); + panel.spawn(( + Text::new(" H/F1 - Toggle help"), + text_style(SMALL_FONT_SIZE, TEXT_COLOR).0, + text_style(SMALL_FONT_SIZE, TEXT_COLOR).1, + )); + panel.spawn(( + Text::new(" Esc - Cancel"), + text_style(SMALL_FONT_SIZE, TEXT_COLOR).0, + text_style(SMALL_FONT_SIZE, TEXT_COLOR).1, + )); + + // Close hint + panel.spawn(Node { + height: Val::Px(8.0), + ..default() + }); + panel.spawn(( + Text::new("Press H to close"), + text_style(SMALL_FONT_SIZE, Color::srgb(0.5, 0.5, 0.5)).0, + text_style(SMALL_FONT_SIZE, Color::srgb(0.5, 0.5, 0.5)).1, + )); + }); +} + +/// Update the stats panel with current player info. +#[allow(clippy::type_complexity)] +pub fn update_stats_panel( + view_model: Option>, + mut health_text: Query<&mut Text, (With, Without, Without)>, + mut mana_text: Query<&mut Text, (With, Without, Without)>, + mut turn_text: Query<&mut Text, (With, Without, Without)>, +) { + let Some(view_model) = view_model else { + return; + }; + + let player = &view_model.0.player; + let (hp_current, hp_max) = player.stats.hp(); + let (mp_current, mp_max) = player.stats.mp(); + + if let Ok(mut text) = health_text.get_single_mut() { + **text = format!("HP: {}/{}", hp_current, hp_max); + } + + if let Ok(mut text) = mana_text.get_single_mut() { + **text = format!("MP: {}/{}", mp_current, mp_max); + } + + if let Ok(mut text) = turn_text.get_single_mut() { + **text = format!("Turn: {}", view_model.0.turn.clock); + } +} + +/// Update the message log with recent messages. +pub fn update_message_log( + message_log: Option>, + mut message_entries: Query<(&MessageEntry, &mut Text)>, +) { + let Some(message_log) = message_log else { + return; + }; + + let messages: Vec<_> = message_log.0.iter().take(8).collect(); + + for (entry, mut text) in message_entries.iter_mut() { + if let Some(msg) = messages.get(entry.index) { + **text = msg.text.clone(); + } else { + **text = String::new(); + } + } +} + +/// Toggle help panel visibility. +pub fn update_help_visibility( + show_help: Res, + mut help_panel: Query<&mut Visibility, With>, +) { + if let Ok(mut visibility) = help_panel.get_single_mut() { + *visibility = if show_help.0 { + Visibility::Visible + } else { + Visibility::Hidden + }; + } +} + +/// Update examine panel based on mouse hover. +pub fn update_examine_panel( + hover_state: Res, + view_model: Option>, + oracle_bundle: Option>, + mut examine_panel: Query<&mut Visibility, With>, + mut examine_text: Query<(&ExamineText, &mut Text)>, +) { + let Some(hover_pos) = hover_state.position else { + // Hide panel when not hovering over map + if let Ok(mut visibility) = examine_panel.get_single_mut() { + *visibility = Visibility::Hidden; + } + return; + }; + + // Show panel when hovering + if let Ok(mut visibility) = examine_panel.get_single_mut() { + *visibility = Visibility::Visible; + } + + let Some(view_model) = view_model else { + return; + }; + + let Some(oracle_bundle) = oracle_bundle else { + return; + }; + + // Get tile info at hover position + let map_oracle = oracle_bundle.0.map.as_ref(); + let tile_info = map_oracle.tile(hover_pos); + let terrain_name = tile_info + .map(|t| format!("{:?}", t.terrain())) + .unwrap_or_else(|| "Void".to_string()); + + // Build display lines + let mut lines: Vec = vec![ + format!("({}, {}) - {}", hover_pos.x, hover_pos.y, terrain_name), + ]; + + // Add entity info if hovering over something + match &hover_state.target { + Some(HoverTarget::Actor { id, is_player }) => { + // Find the actor in view model + if let Some(actor) = view_model.0.actors.iter().find(|a| a.id == *id) { + let (hp_cur, hp_max) = actor.stats.hp(); + let entity_type = if *is_player { "Player" } else { "Enemy" }; + lines.push(entity_type.to_string()); + lines.push(format!("HP: {}/{}", hp_cur, hp_max)); + lines.push(format!("Speed: {}", actor.stats.speed.physical)); + } + } + Some(HoverTarget::Item { id }) => { + if let Some(item) = view_model.0.items.iter().find(|i| i.id == *id) { + lines.push("Item".to_string()); + lines.push(format!("Handle: {}", item.handle.0)); + } + } + Some(HoverTarget::Prop { id }) => { + if let Some(prop) = view_model.0.props.iter().find(|p| p.id == *id) { + lines.push("Prop".to_string()); + lines.push(format!("Kind: {:?}", prop.kind)); + lines.push(format!("Active: {}", if prop.is_active { "Yes" } else { "No" })); + } + } + None => { + // Just show terrain info + } + } + + // Update text elements + for (examine, mut text) in examine_text.iter_mut() { + if let Some(line_text) = lines.get(examine.line) { + **text = line_text.clone(); + } else { + **text = String::new(); + } + } +} diff --git a/crates/client/frontend/bevy/src/ui/styles.rs b/crates/client/frontend/bevy/src/ui/styles.rs new file mode 100644 index 0000000..6ead558 --- /dev/null +++ b/crates/client/frontend/bevy/src/ui/styles.rs @@ -0,0 +1,41 @@ +//! UI styling constants and helpers. + +use bevy::prelude::*; + +/// Background color for panels. +pub const PANEL_BG: Color = Color::srgba(0.1, 0.1, 0.15, 0.9); + +/// Border color for panels. +pub const PANEL_BORDER: Color = Color::srgb(0.3, 0.3, 0.4); + +/// Text color for normal text. +pub const TEXT_COLOR: Color = Color::srgb(0.9, 0.9, 0.9); + +/// Text color for health. +pub const HEALTH_COLOR: Color = Color::srgb(0.8, 0.2, 0.2); + +/// Text color for mana. +pub const MANA_COLOR: Color = Color::srgb(0.2, 0.4, 0.9); + +/// Text color for turn info. +pub const TURN_COLOR: Color = Color::srgb(0.9, 0.8, 0.2); + +/// Font size for headers. +pub const HEADER_FONT_SIZE: f32 = 20.0; + +/// Font size for normal text. +pub const TEXT_FONT_SIZE: f32 = 16.0; + +/// Font size for small text. +pub const SMALL_FONT_SIZE: f32 = 14.0; + +/// Create a text style with the given size and color. +pub fn text_style(size: f32, color: Color) -> (TextFont, TextColor) { + ( + TextFont { + font_size: size, + ..default() + }, + TextColor(color), + ) +} diff --git a/crates/client/cli/Cargo.toml b/crates/client/frontend/cli/Cargo.toml similarity index 64% rename from crates/client/cli/Cargo.toml rename to crates/client/frontend/cli/Cargo.toml index d8b6448..baf666a 100644 --- a/crates/client/cli/Cargo.toml +++ b/crates/client/frontend/cli/Cargo.toml @@ -1,25 +1,27 @@ [package] -name = "client-cli" +name = "client-frontend-cli" version = "0.1.0" edition = "2024" -[[bin]] -name = "client-cli" -path = "src/main.rs" +# No [[bin]] section - this is now a library crate [features] # ZK backend features (propagate to client-bootstrap) -default = ["risc0"] +# No default - backend must be explicitly selected by binary crate +default = [] risc0 = ["client-bootstrap/risc0"] stub = ["client-bootstrap/stub"] sp1 = ["client-bootstrap/sp1"] arkworks = ["client-bootstrap/arkworks"] +# Blockchain integration (propagate to runtime for UI checks) +sui = ["dep:client-blockchain-sui", "runtime/sui"] + [dependencies] # Core dependencies game-core = { workspace = true } runtime = { workspace = true } -client-core = { workspace = true } +client-frontend-core = { workspace = true } client-bootstrap = { workspace = true } # Async runtime @@ -41,3 +43,9 @@ tracing-appender = { workspace = true } # Environment variables dotenvy = { workspace = true } + +# Utilities +hex = { workspace = true } + +# Optional blockchain dependencies +client-blockchain-sui = { workspace = true, optional = true } diff --git a/crates/client/frontend/cli/src/app.rs b/crates/client/frontend/cli/src/app.rs new file mode 100644 index 0000000..71f3ae5 --- /dev/null +++ b/crates/client/frontend/cli/src/app.rs @@ -0,0 +1,117 @@ +//! CLI frontend implementation. +//! +//! Pure UI layer that communicates with the game via RuntimeHandle only. +//! Does NOT own the Runtime - receives a handle for communication. + +use anyhow::Result; +use async_trait::async_trait; +use tokio::sync::mpsc; + +use game_core::{Action, EntityId}; +use runtime::{InteractiveKind, ProviderKind, RuntimeHandle, Topic}; + +use crate::event::{CliEventConsumer, EventLoop}; +use crate::input::CliActionProvider; +use crate::presentation::terminal; +use client_bootstrap::oracles::OracleBundle; +use client_frontend_core::{FrontendConfig, message::MessageLog}; + +/// CLI frontend (pure UI layer). +/// +/// This struct handles: +/// - Terminal rendering +/// - User input collection +/// - Event consumption from runtime +/// - Action submission to runtime +/// +/// It does NOT: +/// - Own the Runtime +/// - Manage Runtime lifecycle +/// - Configure Runtime workers +/// +/// All communication with the game happens via RuntimeHandle. +pub struct CliFrontend { + config: FrontendConfig, + cli_config: crate::config::CliConfig, + oracles: OracleBundle, +} + +impl CliFrontend { + /// Create a new CLI frontend. + /// + /// # Parameters + /// + /// - `config`: Frontend configuration (channels, messages) + /// - `cli_config`: CLI-specific configuration (keybindings, etc.) + /// - `oracles`: Oracle bundle for static game content + pub fn new( + config: FrontendConfig, + cli_config: crate::config::CliConfig, + oracles: OracleBundle, + ) -> Self { + Self { + config, + cli_config, + oracles, + } + } +} + +#[async_trait] +impl client_frontend_core::Frontend for CliFrontend { + async fn run(&mut self, handle: RuntimeHandle) -> Result<()> { + tracing::info!("CLI frontend starting..."); + + // Setup CLI-specific action provider (interactive input) + let (tx_action, rx_action) = mpsc::channel::(self.config.channels.action_buffer); + + let cli_kind = ProviderKind::Interactive(InteractiveKind::CliInput); + + // Register CLI input provider for player + handle.register_provider(cli_kind, CliActionProvider::new(rx_action))?; + + // Bind player to CLI input + handle.bind_entity_provider(EntityId::PLAYER, cli_kind)?; + + // Subscribe to events + let subscriptions = handle.subscribe_multiple(&[Topic::GameState, Topic::Proof]); + let initial_state = handle.query_state().await?; + + // Initialize message log + let mut messages = MessageLog::new(self.config.messages.capacity); + messages.push_text(format!( + "[{}] Welcome to the dungeon.", + initial_state.turn.clock + )); + + // Create event consumer + let consumer = + CliEventConsumer::new(messages, self.config.messages.effect_visibility.clone()); + + // Create event loop + let event_loop = EventLoop::new( + subscriptions, + tx_action, + initial_state.entities.player().id, + consumer, + &initial_state, + self.oracles.clone(), + None, // Use default targeting strategy (ThreatBased) + self.cli_config.clone(), + handle.clone(), + ); + + // Initialize terminal + let mut terminal = terminal::init()?; + let _guard = terminal::TerminalGuard; + + // Run event loop (blocks until user quits) + let _consumer = event_loop.run(&mut terminal).await?; + + // Cleanup + terminal::restore()?; + tracing::info!("CLI frontend exiting"); + + Ok(()) + } +} diff --git a/crates/client/cli/src/config.rs b/crates/client/frontend/cli/src/config.rs similarity index 100% rename from crates/client/cli/src/config.rs rename to crates/client/frontend/cli/src/config.rs diff --git a/crates/client/cli/src/cursor/mod.rs b/crates/client/frontend/cli/src/cursor/mod.rs similarity index 100% rename from crates/client/cli/src/cursor/mod.rs rename to crates/client/frontend/cli/src/cursor/mod.rs diff --git a/crates/client/cli/src/cursor/movement.rs b/crates/client/frontend/cli/src/cursor/movement.rs similarity index 100% rename from crates/client/cli/src/cursor/movement.rs rename to crates/client/frontend/cli/src/cursor/movement.rs diff --git a/crates/client/cli/src/event/consumer.rs b/crates/client/frontend/cli/src/event/consumer.rs similarity index 87% rename from crates/client/cli/src/event/consumer.rs rename to crates/client/frontend/cli/src/event/consumer.rs index 38cc895..1280031 100644 --- a/crates/client/cli/src/event/consumer.rs +++ b/crates/client/frontend/cli/src/event/consumer.rs @@ -1,8 +1,8 @@ //! Maintains the CLI message log in response to runtime events. use runtime::{Event, GameStateEvent}; -use client_bootstrap::config::EffectVisibility; -use client_core::{ +use client_frontend_core::{ + EffectVisibility, event::{EventConsumer, EventImpact}, format::format_action_and_effects, message::{MessageEntry, MessageLevel, MessageLog}, @@ -94,6 +94,17 @@ impl EventConsumer for CliEventConsumer { } EventImpact::redraw() } + Event::GameState(GameStateEvent::StateRestored { + from_nonce, + to_nonce, + }) => { + // Game state was restored from a checkpoint + self.message_log_mut().push_text(format!( + "Game state restored: nonce {} → {}", + from_nonce, to_nonce + )); + EventImpact::redraw() + } Event::Proof(_) => { // Proof events are not displayed in CLI to keep focus on gameplay EventImpact::none() diff --git a/crates/client/cli/src/event/handlers/action.rs b/crates/client/frontend/cli/src/event/handlers/action.rs similarity index 89% rename from crates/client/cli/src/event/handlers/action.rs rename to crates/client/frontend/cli/src/event/handlers/action.rs index a0ac3e1..db036a0 100644 --- a/crates/client/cli/src/event/handlers/action.rs +++ b/crates/client/frontend/cli/src/event/handlers/action.rs @@ -1,7 +1,7 @@ //! Action execution handlers (slots, abilities, targeting). use anyhow::Result; -use client_core::EventConsumer; +use client_frontend_core::EventConsumer; use game_core::{Action, EntityId}; use super::super::EventLoop; @@ -112,15 +112,25 @@ where if *require_entity { // Must have an entity at cursor position if let Some(entity_id) = self.app_state.highlighted_entity { - // Verify entity is not the player and is alive - let is_valid = self.view_model.actors.iter().any(|actor| { + // Verify entity exists in the world (check all entity types) + let is_actor = self.view_model.actors.iter().any(|actor| { actor.id == entity_id && actor.id != EntityId::PLAYER && actor.stats.resource_current.hp > 0 }); - - if is_valid { - Some(ActionInput::Entity(entity_id)) + let is_item = self + .view_model + .items + .iter() + .any(|item| item.id == entity_id); + let is_prop = self + .view_model + .props + .iter() + .any(|prop| prop.id == entity_id); + + if is_actor || is_item || is_prop { + Some(ActionInput::Target(entity_id)) } else { // Invalid entity self.consumer.message_log_mut().push_text(format!( @@ -167,10 +177,10 @@ where &mut self, action_kind: game_core::ActionKind, ) -> Result<()> { - use game_core::{ActionInput, CharacterAction, env::TablesOracle}; + use game_core::{ActionInput, CharacterAction, env::ActionOracle}; - // Get targeting mode from action profile via TablesOracle - let action_profile = self.oracles.tables.action_profile(action_kind); + // Get targeting mode from action profile via ActionOracle + let action_profile = self.oracles.actions.action_profile(action_kind); let targeting = action_profile.targeting; // Check targeting mode @@ -186,7 +196,7 @@ where let action = CharacterAction::new( EntityId::PLAYER, action_kind, - ActionInput::Entity(EntityId::PLAYER), + ActionInput::Target(EntityId::PLAYER), ); self.tx_action.send(Action::Character(action)).await?; } diff --git a/crates/client/frontend/cli/src/event/handlers/input.rs b/crates/client/frontend/cli/src/event/handlers/input.rs new file mode 100644 index 0000000..643e51c --- /dev/null +++ b/crates/client/frontend/cli/src/event/handlers/input.rs @@ -0,0 +1,773 @@ +//! Input handling (keyboard and directional input). + +use anyhow::Result; +use client_frontend_core::EventConsumer; +use crossterm::event::{self as term_event, Event as TermEvent, KeyEvent, KeyEventKind}; +use game_core::{Action, EntityId, env::MapOracle}; +use tokio::time::Duration; + +use super::super::EventLoop; +use crate::{ + cursor::CursorMovement, + input::KeyAction, + presentation::terminal::Tui, + state::{AppMode, TargetingInputMode}, +}; + +impl EventLoop +where + C: EventConsumer, +{ + /// Poll for keyboard input and handle UI interactions. + pub(in crate::event) async fn handle_input_tick(&mut self, terminal: &mut Tui) -> Result { + if !term_event::poll(Duration::from_millis(0))? { + return Ok(false); + } + + match term_event::read()? { + TermEvent::Key(key) if key.kind == KeyEventKind::Press => { + self.handle_key_press(key, terminal).await + } + TermEvent::Resize(_, _) => { + self.render(terminal)?; + Ok(false) + } + _ => Ok(false), + } + } + + /// Handle key press and dispatch to appropriate handler. + pub(in crate::event) async fn handle_key_press( + &mut self, + key: KeyEvent, + terminal: &mut Tui, + ) -> Result { + match self.input.handle_key(key, &self.app_state.mode) { + KeyAction::Quit => { + self.consumer + .message_log_mut() + .push_text(format!("[{}] Quitting...", self.view_model.turn.clock)); + + // Just render the quit message + self.render(terminal)?; + Ok(true) + } + KeyAction::Submit(action) => { + if self.tx_action.send(action).await.is_err() { + tracing::error!("Action channel closed"); + return Ok(true); + } + Ok(false) + } + KeyAction::ToggleExamine => { + let cursor_pos = if let Some(entity_id) = self.app_state.highlighted_entity { + // Place cursor at highlighted entity's position + self.view_model + .actors + .iter() + .find(|a| a.id == entity_id) + .and_then(|a| a.position) + .or(self.view_model.player.position) + .unwrap_or_else(|| game_core::Position::new(0, 0)) + } else { + // No highlighted entity - default to player + self.view_model + .player + .position + .unwrap_or_else(|| game_core::Position::new(0, 0)) + }; + + self.app_state.toggle_examine(cursor_pos); + self.render(terminal)?; + Ok(false) + } + KeyAction::ExitModal => { + self.app_state.exit_to_normal(); + self.compute_auto_target(); + self.render(terminal)?; + Ok(false) + } + KeyAction::MoveCursor(direction) => { + // Check if in SelectDirection targeting mode + if let AppMode::Targeting(targeting_state) = &mut self.app_state.mode + && let TargetingInputMode::Direction { selected } = + &mut targeting_state.input_mode + { + // Update selected direction + *selected = Some(direction); + self.render(terminal)?; + return Ok(false); + } + + // Normal cursor movement (ExamineManual mode or SelectPosition targeting) + if let Some(cursor) = &mut self.app_state.manual_cursor { + let (dx, dy) = direction.to_delta(); + let dimensions = self.oracles.map.dimensions(); + cursor.move_by(dx, dy, dimensions.width, dimensions.height); + + // Update highlighted entity to first entity at new cursor position + self.update_highlighted_at_cursor(); + self.render(terminal)?; + } + Ok(false) + } + KeyAction::NextEntity => { + if self.app_state.mode == AppMode::Normal { + // Normal mode: cycle through all NPCs + self.cycle_highlighted_entity(1); + } else { + // Manual mode: cycle through entities at cursor position + self.cycle_entities_at_cursor(1); + } + self.render(terminal)?; + Ok(false) + } + KeyAction::PrevEntity => { + if self.app_state.mode == AppMode::Normal { + // Normal mode: cycle through all NPCs (backwards) + self.cycle_highlighted_entity(-1); + } else { + // Manual mode: cycle through entities at cursor position (backwards) + self.cycle_entities_at_cursor(-1); + } + self.render(terminal)?; + Ok(false) + } + KeyAction::DirectionalInput(direction) => { + self.handle_directional_input(direction).await?; + Ok(false) + } + KeyAction::UseSlot(slot) => { + self.handle_use_slot(slot).await?; + self.render(terminal)?; + Ok(false) + } + KeyAction::OpenAbilityMenu => { + self.handle_open_ability_menu().await?; + self.render(terminal)?; + Ok(false) + } + KeyAction::SelectAbilityForSlot(ability_idx) => { + self.handle_select_ability(ability_idx)?; + self.render(terminal)?; + Ok(false) + } + KeyAction::ConfirmTarget => { + self.handle_confirm_target().await?; + self.render(terminal)?; + Ok(false) + } + KeyAction::PickupItem => { + self.handle_pickup_item().await?; + self.render(terminal)?; + Ok(false) + } + KeyAction::SaveGame => { + self.handle_save_game().await?; + self.render(terminal)?; + Ok(false) + } + KeyAction::OpenStartScreen => { + self.handle_open_start_screen().await?; + self.render(terminal)?; + Ok(false) + } + KeyAction::OpenSaveMenu => { + self.handle_open_save_menu().await?; + self.render(terminal)?; + Ok(false) + } + KeyAction::MenuUp => { + self.handle_menu_up(); + self.render(terminal)?; + Ok(false) + } + KeyAction::MenuDown => { + self.handle_menu_down(); + self.render(terminal)?; + Ok(false) + } + KeyAction::MenuConfirm => { + self.handle_menu_confirm().await?; + self.render(terminal)?; + Ok(false) + } + KeyAction::UploadToWalrus => { + self.handle_upload_to_walrus().await?; + self.render(terminal)?; + Ok(false) + } + KeyAction::SubmitProof => { + self.handle_submit_proof().await?; + self.render(terminal)?; + Ok(false) + } + KeyAction::CreateSession => { + self.handle_create_session().await?; + self.render(terminal)?; + Ok(false) + } + KeyAction::None => Ok(false), + } + } + + /// Handle directional input: Bump-to-attack or Move. + pub(in crate::event) async fn handle_directional_input( + &mut self, + direction: game_core::CardinalDirection, + ) -> Result<()> { + use game_core::{ActionInput, ActionKind, CharacterAction}; + + let Some(player_pos) = self.view_model.player.position else { + return Ok(()); + }; + let (dx, dy) = direction.offset(); + let target_pos = game_core::Position::new(player_pos.x + dx, player_pos.y + dy); + + // Check if there's an enemy at target position + let enemy_at_target = self.view_model.actors.iter().find(|actor| { + actor.id != EntityId::PLAYER + && actor.position == Some(target_pos) + && actor.stats.resource_current.hp > 0 + }); + + let action = if let Some(enemy) = enemy_at_target { + // Bump-to-attack: Attack the enemy + CharacterAction::new( + EntityId::PLAYER, + ActionKind::MeleeAttack, + ActionInput::Target(enemy.id), + ) + } else { + // No enemy: Just move + CharacterAction::new( + EntityId::PLAYER, + ActionKind::Move, + ActionInput::Direction(direction), + ) + }; + + self.tx_action.send(Action::Character(action)).await?; + Ok(()) + } + + /// Handle picking up an item at the player's position. + pub(in crate::event) async fn handle_pickup_item(&mut self) -> Result<()> { + use game_core::{ActionInput, ActionKind, CharacterAction}; + + let Some(player_pos) = self.view_model.player.position else { + return Ok(()); + }; + + // Find item at player's position + let item_at_pos = self + .view_model + .items + .iter() + .find(|item| item.position == player_pos); + + if let Some(item) = item_at_pos { + // Create PickupItem action with Target input (item entity ID) + let action = CharacterAction::new( + EntityId::PLAYER, + ActionKind::PickupItem, + ActionInput::Target(item.id), + ); + + self.tx_action.send(Action::Character(action)).await?; + } else { + // No item at player's position - optionally show a message + self.consumer + .message_log_mut() + .push_text("No item here to pick up.".to_string()); + } + + Ok(()) + } + + /// Handle save game (Ctrl+S) - create manual checkpoint. + pub(in crate::event) async fn handle_save_game(&mut self) -> Result<()> { + self.consumer + .message_log_mut() + .push_text("Saving game...".to_string()); + + match self.runtime_handle.create_checkpoint().await { + Ok(nonce) => { + self.consumer + .message_log_mut() + .push_text(format!("Game saved at nonce {} (Ctrl+O to load)", nonce)); + } + Err(e) => { + self.consumer + .message_log_mut() + .push_text(format!("Failed to save: {}", e)); + } + } + + Ok(()) + } + + /// Handle open save menu (Ctrl+O) - enter full-screen save menu mode. + pub(in crate::event) async fn handle_open_start_screen(&mut self) -> Result<()> { + use client_bootstrap::list_sessions; + + // Query runtime for save data directory + // For now, use environment variable or default fallback + let save_dir = std::env::var("SAVE_DATA_DIR") + .ok() + .map(std::path::PathBuf::from) + .unwrap_or_else(|| std::path::PathBuf::from("./save_data")); + + // List all available sessions + match list_sessions(&save_dir) { + Ok(sessions) => { + // Enter start screen mode + self.app_state.enter_start_screen(sessions); + } + Err(e) => { + self.consumer + .message_log_mut() + .push_text(format!("Failed to list sessions: {}", e)); + } + } + + Ok(()) + } + + pub(in crate::event) async fn handle_open_save_menu(&mut self) -> Result<()> { + use runtime::ActionBatchStatus; + + // List all checkpoints and filter out InProgress + match self.runtime_handle.list_all_checkpoints().await { + Ok(all_batches) => { + // Filter out InProgress batches (end_nonce not finalized yet) + let batches: Vec<_> = all_batches + .into_iter() + .filter(|b| !matches!(b.status, ActionBatchStatus::InProgress)) + .collect(); + + // Fetch blockchain session info (if available) + #[cfg(feature = "sui")] + let session_info = match self.runtime_handle.get_blockchain_session_info().await { + Ok(info) => info, + Err(e) => { + self.consumer + .message_log_mut() + .push_text(format!("Failed to fetch session info: {}", e)); + None + } + }; + + // Enter save menu mode with finalized checkpoints + self.app_state.enter_save_menu( + batches, + #[cfg(feature = "sui")] + session_info, + ); + } + Err(e) => { + self.consumer + .message_log_mut() + .push_text(format!("Failed to list checkpoints: {}", e)); + } + } + + Ok(()) + } + + /// Handle menu navigation up (StartScreen, SaveMenu). + pub(in crate::event) fn handle_menu_up(&mut self) { + use crate::state::AppMode; + + match &mut self.app_state.mode { + AppMode::StartScreen(start_state) => { + if start_state.selected > 0 { + start_state.selected -= 1; + } + } + AppMode::SaveMenu(menu_state) => { + if menu_state.selected_index > 0 { + menu_state.selected_index -= 1; + } + } + _ => {} + } + } + + /// Handle menu navigation down (StartScreen, SaveMenu). + pub(in crate::event) fn handle_menu_down(&mut self) { + use crate::state::AppMode; + + match &mut self.app_state.mode { + AppMode::StartScreen(start_state) => { + let max_index = start_state.sessions.len(); // 0 = New Game, 1+ = sessions + if start_state.selected < max_index { + start_state.selected += 1; + } + } + AppMode::SaveMenu(menu_state) => { + if menu_state.selected_index < menu_state.saved_states.len().saturating_sub(1) { + menu_state.selected_index += 1; + } + } + _ => {} + } + } + + /// Handle menu confirm (StartScreen session selection, SaveMenu load state). + pub(in crate::event) async fn handle_menu_confirm(&mut self) -> Result<()> { + use crate::state::AppMode; + + if let AppMode::StartScreen(start_state) = &self.app_state.mode { + if start_state.selected == 0 { + // New Game selected + self.consumer.message_log_mut().push_text( + "New Game not yet implemented. Please restart the client to start a new game." + .to_string(), + ); + self.app_state.exit_to_normal(); + } else { + // Continue from selected session + let session_idx = start_state.selected - 1; + if let Some(session) = start_state.sessions.get(session_idx) { + self.consumer.message_log_mut().push_text(format!( + "Session resumption not yet implemented. Please restart the client to continue session: {}", + session.session_id + )); + self.app_state.exit_to_normal(); + } + } + return Ok(()); + } + + if let AppMode::SaveMenu(menu_state) = &self.app_state.mode { + if menu_state.saved_states.is_empty() { + // No saved states - just exit + self.app_state.exit_to_normal(); + return Ok(()); + } + + // Get selected state + let selected_state = &menu_state.saved_states[menu_state.selected_index]; + let target_nonce = selected_state.nonce; + + self.consumer + .message_log_mut() + .push_text(format!("Restoring state at nonce {}...", target_nonce)); + + // Use restore_state to actually replace the simulation worker's state + match self.runtime_handle.restore_state(target_nonce).await { + Ok(()) => { + self.consumer.message_log_mut().push_text(format!( + "Successfully restored state at nonce {}", + target_nonce + )); + + // Prepare next turn to refresh the ViewModel + match self.runtime_handle.prepare_next_turn().await { + Ok((_, restored_state)) => { + // Update ViewModel with restored state + self.view_model = + client_frontend_core::view_model::ViewModel::from_initial_state( + &restored_state, + self.oracles.map.as_ref(), + ); + + self.consumer.message_log_mut().push_text(format!( + "State restored (turn {})", + restored_state.turn.clock + )); + + // Recompute auto-target for new state + self.compute_auto_target(); + } + Err(e) => { + self.consumer + .message_log_mut() + .push_text(format!("Failed to refresh view: {}", e)); + } + } + + // Exit back to normal mode + self.app_state.exit_to_normal(); + } + Err(e) => { + self.consumer + .message_log_mut() + .push_text(format!("Failed to restore state: {}", e)); + + // Stay in menu on error + } + } + } + + Ok(()) + } + + /// Handle upload to Walrus (W key in SaveMenu). + pub(in crate::event) async fn handle_upload_to_walrus(&mut self) -> Result<()> { + #[cfg(not(feature = "sui"))] + { + Ok(()) + } + + #[cfg(feature = "sui")] + { + use crate::state::AppMode; + use runtime::ActionBatchStatus; + + if let AppMode::SaveMenu(menu_state) = &self.app_state.mode { + if menu_state.saved_states.is_empty() { + return Ok(()); + } + + // Get selected state and its associated batch + let selected_state = &menu_state.saved_states[menu_state.selected_index]; + + if let Some(batch_idx) = selected_state.batch_index { + if let Some(batch) = menu_state.action_batches.get(batch_idx) { + // Check if upload is available (must be Proven) + let can_upload = matches!(batch.status, ActionBatchStatus::Proven { .. }); + + if !can_upload { + self.app_state.save_menu_log.push_text(format!( + "Cannot upload to Walrus for batch at nonce {} (status: {:?})", + batch.start_nonce, batch.status + )); + return Ok(()); + } + + // Upload to Walrus + self.app_state.save_menu_log.push_text(format!( + "Uploading action log for batch {} → {} to Walrus...", + batch.start_nonce, batch.end_nonce + )); + + #[cfg(feature = "sui")] + { + match self + .runtime_handle + .upload_to_walrus(batch.start_nonce) + .await + { + Ok((blob_object_id, walrus_blob_id)) => { + self.app_state.save_menu_log.push_text(format!( + "✓ Uploaded to Walrus successfully!\nBlob Object: {}\nWalrus ID: {}", + blob_object_id, + walrus_blob_id + )); + + // Refresh menu state to show updated batch status + if let Err(e) = self.refresh_save_menu().await { + tracing::warn!( + "Failed to refresh save menu after upload: {}", + e + ); + } + } + Err(e) => { + self.app_state + .save_menu_log + .push_text(format!("✗ Failed to upload to Walrus: {}", e)); + } + } + } + } else { + self.app_state + .save_menu_log + .push_text("No associated proof batch found".to_string()); + } + } else { + self.app_state + .save_menu_log + .push_text("No associated proof batch for this state".to_string()); + } + } + + Ok(()) + } + } + + /// Handle submit proof (S key in SaveMenu). + pub(in crate::event) async fn handle_submit_proof(&mut self) -> Result<()> { + #[cfg(not(feature = "sui"))] + { + Ok(()) + } + + #[cfg(feature = "sui")] + { + use crate::state::AppMode; + use runtime::ActionBatchStatus; + + if let AppMode::SaveMenu(menu_state) = &self.app_state.mode { + if menu_state.saved_states.is_empty() { + return Ok(()); + } + + // Get selected state and its associated batch + let selected_state = &menu_state.saved_states[menu_state.selected_index]; + + if let Some(batch_idx) = selected_state.batch_index { + if let Some(batch) = menu_state.action_batches.get(batch_idx) { + // Check if submission is available (must be BlobUploaded) + let can_submit = + matches!(batch.status, ActionBatchStatus::BlobUploaded { .. }); + + if !can_submit { + self.app_state.save_menu_log.push_text(format!( + "Cannot submit proof for batch at nonce {} (status: {:?})", + batch.start_nonce, batch.status + )); + return Ok(()); + } + + // Submit to blockchain + self.app_state.save_menu_log.push_text(format!( + "Submitting proof for batch {} → {} to blockchain...", + batch.start_nonce, batch.end_nonce + )); + + #[cfg(feature = "sui")] + { + match self + .runtime_handle + .submit_to_blockchain(batch.start_nonce) + .await + { + Ok(tx_digest) => { + self.app_state.save_menu_log.push_text(format!( + "✓ Submitted to blockchain successfully!\nTx Digest: {}", + tx_digest + )); + + // Refresh menu state to show updated batch status + if let Err(e) = self.refresh_save_menu().await { + tracing::warn!( + "Failed to refresh save menu after submit: {}", + e + ); + } + } + Err(e) => { + self.app_state.save_menu_log.push_text(format!( + "✗ Failed to submit to blockchain: {}", + e + )); + } + } + } + } else { + self.app_state + .save_menu_log + .push_text("No associated proof batch found".to_string()); + } + } else { + self.app_state + .save_menu_log + .push_text("No associated proof batch for this state".to_string()); + } + } + + Ok(()) + } + } + + /// Handle create session on blockchain (C key in SaveMenu). + pub(in crate::event) async fn handle_create_session(&mut self) -> Result<()> { + #[cfg(not(feature = "sui"))] + { + Ok(()) + } + + #[cfg(feature = "sui")] + { + use crate::state::AppMode; + + if !matches!(self.app_state.mode, AppMode::SaveMenu(_)) { + return Ok(()); + } + + self.app_state + .save_menu_log + .push_text("Creating session on blockchain using state 0...".to_string()); + + match self.runtime_handle.create_session_on_blockchain().await { + Ok(session_object_id) => { + self.app_state.save_menu_log.push_text(format!( + "✓ Session created successfully!\nSession Object ID: {}", + session_object_id + )); + + // Refresh menu state to show updated session info + if let Err(e) = self.refresh_save_menu().await { + tracing::warn!("Failed to refresh save menu after session creation: {}", e); + } + } + Err(e) => { + self.app_state + .save_menu_log + .push_text(format!("✗ Failed to create session: {}", e)); + } + } + + Ok(()) + } + } + + /// Refresh Save Menu state with latest batch data from runtime. + /// + /// Used after blockchain operations (upload/submit) to show updated status immediately. + pub(in crate::event) async fn refresh_save_menu(&mut self) -> Result<()> { + use crate::state::AppMode; + use runtime::ActionBatchStatus; + + // Only refresh if we're in Save Menu mode + if let AppMode::SaveMenu(current_state) = &self.app_state.mode { + let selected_index = current_state.selected_index; + + match self.runtime_handle.list_all_checkpoints().await { + Ok(all_batches) => { + // Filter out InProgress batches + let batches: Vec<_> = all_batches + .into_iter() + .filter(|b| !matches!(b.status, ActionBatchStatus::InProgress)) + .collect(); + + // Fetch blockchain session info (if available) + #[cfg(feature = "sui")] + let session_info = match self.runtime_handle.get_blockchain_session_info().await + { + Ok(info) => info, + Err(e) => { + self.app_state + .save_menu_log + .push_text(format!("Failed to fetch session info: {}", e)); + None + } + }; + + // Re-enter save menu with updated batches, preserving selection + self.app_state.enter_save_menu( + batches, + #[cfg(feature = "sui")] + session_info, + ); + + // Restore selected index (capped at new list length) + if let AppMode::SaveMenu(new_state) = &mut self.app_state.mode { + new_state.selected_index = + selected_index.min(new_state.saved_states.len().saturating_sub(1)); + } + } + Err(e) => { + self.app_state + .save_menu_log + .push_text(format!("Failed to refresh menu: {}", e)); + } + } + } + + Ok(()) + } +} diff --git a/crates/client/cli/src/event/handlers/mod.rs b/crates/client/frontend/cli/src/event/handlers/mod.rs similarity index 100% rename from crates/client/cli/src/event/handlers/mod.rs rename to crates/client/frontend/cli/src/event/handlers/mod.rs diff --git a/crates/client/cli/src/event/handlers/rendering.rs b/crates/client/frontend/cli/src/event/handlers/rendering.rs similarity index 96% rename from crates/client/cli/src/event/handlers/rendering.rs rename to crates/client/frontend/cli/src/event/handlers/rendering.rs index 6e88082..eae5f52 100644 --- a/crates/client/cli/src/event/handlers/rendering.rs +++ b/crates/client/frontend/cli/src/event/handlers/rendering.rs @@ -1,7 +1,7 @@ //! Rendering handlers. use anyhow::Result; -use client_core::EventConsumer; +use client_frontend_core::EventConsumer; use super::super::EventLoop; use crate::presentation::{terminal::Tui, ui}; diff --git a/crates/client/cli/src/event/handlers/targeting.rs b/crates/client/frontend/cli/src/event/handlers/targeting.rs similarity index 73% rename from crates/client/cli/src/event/handlers/targeting.rs rename to crates/client/frontend/cli/src/event/handlers/targeting.rs index 7c3a72e..8ca2b7c 100644 --- a/crates/client/cli/src/event/handlers/targeting.rs +++ b/crates/client/frontend/cli/src/event/handlers/targeting.rs @@ -1,6 +1,6 @@ //! Targeting and entity selection handlers. -use client_core::EventConsumer; +use client_frontend_core::EventConsumer; use game_core::EntityId; use super::super::EventLoop; @@ -43,7 +43,7 @@ where #[allow(dead_code)] pub(in crate::event) fn set_targeting_strategy( &mut self, - strategy: Box, + strategy: Box, ) { self.target_selector.set_strategy(strategy); } @@ -79,18 +79,40 @@ where /// Cycle through entities at cursor position in Manual mode (Tab key). /// /// Direction: +1 for next, -1 for previous. - /// Only cycles through NPCs at the current cursor position. + /// Cycles through all entity types: NPCs, Items, and Props at the current cursor position. pub(in crate::event) fn cycle_entities_at_cursor(&mut self, direction: i32) { let Some(cursor_pos) = self.app_state.manual_cursor.as_ref().map(|c| c.position) else { return; }; - // Collect all NPCs at cursor position - let entities_here: Vec<_> = self - .view_model - .npcs() - .filter(|npc| npc.position == Some(cursor_pos)) - .collect(); + // Collect all entities at cursor position (NPCs, Items, Props) + let mut entities_here: Vec = Vec::new(); + + // Add NPCs + entities_here.extend( + self.view_model + .npcs() + .filter(|npc| npc.position == Some(cursor_pos)) + .map(|npc| npc.id), + ); + + // Add Items + entities_here.extend( + self.view_model + .items + .iter() + .filter(|item| item.position == cursor_pos) + .map(|item| item.id), + ); + + // Add Props + entities_here.extend( + self.view_model + .props + .iter() + .filter(|prop| prop.position == cursor_pos) + .map(|prop| prop.id), + ); if entities_here.is_empty() { // No entities at cursor - clear highlight @@ -102,7 +124,7 @@ where let current_idx = self .app_state .highlighted_entity - .and_then(|id| entities_here.iter().position(|npc| npc.id == id)) + .and_then(|id| entities_here.iter().position(|&eid| eid == id)) .unwrap_or(0); // Cycle with wrapping @@ -110,23 +132,38 @@ where (current_idx as i32 + direction).rem_euclid(entities_here.len() as i32) as usize; self.app_state - .set_highlighted_entity(Some(entities_here[new_idx].id)); + .set_highlighted_entity(Some(entities_here[new_idx])); } /// Update highlighted entity when cursor moves in Manual mode. /// - /// Highlights the first NPC at the new cursor position, or None if no entities. + /// Highlights the first entity at the new cursor position, prioritizing NPCs > Items > Props. + /// Returns None if no entities at cursor. pub(in crate::event) fn update_highlighted_at_cursor(&mut self) { let Some(cursor_pos) = self.app_state.manual_cursor.as_ref().map(|c| c.position) else { return; }; - // Find first NPC at cursor position + // Priority: NPCs first, then Items, then Props let entity_at_cursor = self .view_model .npcs() .find(|npc| npc.position == Some(cursor_pos)) - .map(|npc| npc.id); + .map(|npc| npc.id) + .or_else(|| { + self.view_model + .items + .iter() + .find(|item| item.position == cursor_pos) + .map(|item| item.id) + }) + .or_else(|| { + self.view_model + .props + .iter() + .find(|prop| prop.position == cursor_pos) + .map(|prop| prop.id) + }); self.app_state.set_highlighted_entity(entity_at_cursor); } diff --git a/crates/client/cli/src/event/loop.rs b/crates/client/frontend/cli/src/event/loop.rs similarity index 70% rename from crates/client/cli/src/event/loop.rs rename to crates/client/frontend/cli/src/event/loop.rs index 43259f2..5db397c 100644 --- a/crates/client/cli/src/event/loop.rs +++ b/crates/client/frontend/cli/src/event/loop.rs @@ -9,7 +9,7 @@ use std::collections::HashMap; use anyhow::Result; use game_core::{Action, EntityId, GameState}; -use runtime::{Event as RuntimeEvent, RuntimeHandle, Topic}; +use runtime::{Event as RuntimeEvent, Topic}; use tokio::{ sync::{broadcast, broadcast::error::RecvError, mpsc}, time::{self, Duration}, @@ -17,13 +17,15 @@ use tokio::{ use crate::{input::InputHandler, presentation::terminal::Tui, state::AppState}; use client_bootstrap::oracles::OracleBundle; -use client_core::{ +use client_frontend_core::{ EventConsumer, services::{ViewModelUpdater, targeting::TargetSelector}, view_model::ViewModel, }; +use runtime::RuntimeHandle; const FRAME_INTERVAL_MS: u64 = 16; +const SAVE_MENU_REFRESH_INTERVAL_MS: u64 = 2000; // Refresh Save Menu every 2 seconds /// Event loop managing ViewModel state and coordinating UI updates. /// @@ -36,7 +38,6 @@ pub struct EventLoop where C: EventConsumer, { - pub(crate) handle: RuntimeHandle, pub(crate) subscriptions: HashMap>, pub(crate) tx_action: mpsc::Sender, pub(crate) input: InputHandler, @@ -50,6 +51,8 @@ where pub(crate) oracles: OracleBundle, /// CLI UI configuration pub(crate) cli_config: crate::config::CliConfig, + /// Runtime handle for save/load operations + pub(crate) runtime_handle: RuntimeHandle, } impl EventLoop @@ -58,7 +61,6 @@ where { #[allow(clippy::too_many_arguments)] pub fn new( - handle: RuntimeHandle, subscriptions: HashMap>, tx_action: mpsc::Sender, player_entity: EntityId, @@ -67,11 +69,11 @@ where oracles: OracleBundle, target_selector: Option, cli_config: crate::config::CliConfig, + runtime_handle: RuntimeHandle, ) -> Self { let view_model = ViewModel::from_initial_state(initial_state, oracles.map.as_ref()); Self { - handle, subscriptions, tx_action, input: InputHandler::new(player_entity), @@ -81,6 +83,7 @@ where target_selector: target_selector.unwrap_or_default(), oracles, cli_config, + runtime_handle, } } @@ -93,6 +96,11 @@ where let mut game_rx = self.subscriptions.remove(&Topic::GameState); let mut proof_rx = self.subscriptions.remove(&Topic::Proof); + // Save Menu refresh interval + let mut save_menu_refresh_interval = + time::interval(Duration::from_millis(SAVE_MENU_REFRESH_INTERVAL_MS)); + save_menu_refresh_interval.set_missed_tick_behavior(time::MissedTickBehavior::Skip); + loop { tokio::select! { result = async { game_rx.as_mut().unwrap().recv().await }, if game_rx.is_some() => { @@ -110,6 +118,11 @@ where break; } } + _ = save_menu_refresh_interval.tick() => { + if self.handle_save_menu_refresh_tick(terminal).await? { + break; + } + } } } @@ -124,16 +137,27 @@ where ) -> Result { match result { Ok(event) => { + // Check if we need to refresh Save Menu on Proof events + let should_refresh_save_menu = matches!(event, RuntimeEvent::Proof(_)) + && matches!(self.app_state.mode, crate::state::AppMode::SaveMenu(_)); + // Let consumer process event (message logging, etc.) let impact = self.consumer.on_event(&event); + // If Save Menu is open and we got a Proof event, refresh it + if should_refresh_save_menu { + if let Err(e) = self.refresh_save_menu().await { + tracing::warn!("Failed to refresh save menu: {}", e); + } + self.render(terminal)?; + return Ok(false); + } + // Update ViewModel incrementally using ViewModelUpdater service if impact.requires_redraw { - let state = self.handle.query_state().await?; let scope = ViewModelUpdater::update( &mut self.view_model, &event, - &state, self.oracles.map.as_ref(), ); @@ -156,4 +180,21 @@ where } } } + + /// Handle Save Menu periodic refresh tick. + /// + /// Refreshes the Save Menu state every 2 seconds to pick up batch status changes + /// from background ProverWorker (proving → proven transitions). + async fn handle_save_menu_refresh_tick(&mut self, terminal: &mut Tui) -> Result { + // Only refresh if Save Menu is currently open + if matches!(self.app_state.mode, crate::state::AppMode::SaveMenu(_)) { + if let Err(e) = self.refresh_save_menu().await { + tracing::warn!("Failed to auto-refresh save menu: {}", e); + } else { + // Re-render to show updated status + self.render(terminal)?; + } + } + Ok(false) + } } diff --git a/crates/client/cli/src/event/mod.rs b/crates/client/frontend/cli/src/event/mod.rs similarity index 100% rename from crates/client/cli/src/event/mod.rs rename to crates/client/frontend/cli/src/event/mod.rs diff --git a/crates/client/cli/src/input/mod.rs b/crates/client/frontend/cli/src/input/mod.rs similarity index 78% rename from crates/client/cli/src/input/mod.rs rename to crates/client/frontend/cli/src/input/mod.rs index 2f11212..ecfe653 100644 --- a/crates/client/cli/src/input/mod.rs +++ b/crates/client/frontend/cli/src/input/mod.rs @@ -13,8 +13,10 @@ pub use provider::CliActionProvider; /// High-level outcome of processing a keyboard event. #[derive(Debug)] pub enum KeyAction { - /// Exit the application. + /// Exit the application completely. Quit, + /// Open start screen (New Game / Continue). + OpenStartScreen, /// Submit the decoded game action to the runtime. Submit(Action), /// Toggle between Normal (auto-target) and ExamineManual mode. @@ -37,6 +39,24 @@ pub enum KeyAction { SelectAbilityForSlot(usize), /// Confirm target selection in targeting mode. ConfirmTarget, + /// Pick up item at player's position. + PickupItem, + /// Create a manual checkpoint (save game). + SaveGame, + /// Open save/load menu to view checkpoints. + OpenSaveMenu, + /// Navigate up in menu (SaveMenu, Inventory, etc.). + MenuUp, + /// Navigate down in menu (SaveMenu, Inventory, etc.). + MenuDown, + /// Confirm menu selection (SaveMenu load, etc.). + MenuConfirm, + /// Upload action log to Walrus (SaveMenu). + UploadToWalrus, + /// Submit proof to blockchain (SaveMenu). + SubmitProof, + /// Create session on blockchain (SaveMenu). + CreateSession, /// No meaningful command was produced. None, } @@ -68,10 +88,12 @@ impl InputHandler { use crate::state::AppMode; match mode { + AppMode::StartScreen(_) => self.handle_start_screen_mode(key), AppMode::Normal => self.handle_normal_mode(key), AppMode::ExamineManual => self.handle_examine_mode(key), AppMode::AbilityMenu => self.handle_ability_menu(key), AppMode::Targeting(targeting_state) => self.handle_targeting_mode(key, targeting_state), + AppMode::SaveMenu(_) => self.handle_save_menu_mode(key), AppMode::Inventory => KeyAction::None, // TODO: Future } } @@ -109,8 +131,23 @@ impl InputHandler { // Commands KeyCode::Char('a') => KeyAction::OpenAbilityMenu, KeyCode::Char('x') => KeyAction::ToggleExamine, + KeyCode::Char('g') => KeyAction::PickupItem, + KeyCode::Char('s') => { + if key.modifiers.contains(KeyModifiers::CONTROL) { + KeyAction::SaveGame // Ctrl+S to save + } else { + KeyAction::None + } + } + KeyCode::Char('o') => { + if key.modifiers.contains(KeyModifiers::CONTROL) { + KeyAction::OpenSaveMenu // Ctrl+O to open save menu + } else { + KeyAction::None + } + } KeyCode::Char(' ') | KeyCode::Char('.') => self.wait(), - KeyCode::Char('q') => KeyAction::Quit, + KeyCode::Char('q') => KeyAction::OpenStartScreen, // Tab cycling (for auto-target in Normal mode) KeyCode::Tab => { @@ -220,6 +257,31 @@ impl InputHandler { } } + /// Handle input in Start Screen mode (arrow keys, Enter, ESC). + fn handle_start_screen_mode(&self, key: KeyEvent) -> KeyAction { + match key.code { + KeyCode::Up | KeyCode::Char('k') => KeyAction::MenuUp, + KeyCode::Down | KeyCode::Char('j') => KeyAction::MenuDown, + KeyCode::Enter => KeyAction::MenuConfirm, + KeyCode::Esc | KeyCode::Char('q') => KeyAction::Quit, + _ => KeyAction::None, + } + } + + /// Handle input in Save Menu mode (arrow keys, Enter, C, W, S, ESC). + fn handle_save_menu_mode(&self, key: KeyEvent) -> KeyAction { + match key.code { + KeyCode::Up | KeyCode::Char('k') => KeyAction::MenuUp, + KeyCode::Down | KeyCode::Char('j') => KeyAction::MenuDown, + KeyCode::Enter => KeyAction::MenuConfirm, + KeyCode::Char('c') | KeyCode::Char('C') => KeyAction::CreateSession, + KeyCode::Char('w') | KeyCode::Char('W') => KeyAction::UploadToWalrus, + KeyCode::Char('s') | KeyCode::Char('S') => KeyAction::SubmitProof, + KeyCode::Esc | KeyCode::Char('q') => KeyAction::ExitModal, + _ => KeyAction::None, + } + } + fn wait(&self) -> KeyAction { let character_action = CharacterAction::new(self.player_entity, ActionKind::Wait, ActionInput::None); diff --git a/crates/client/cli/src/input/provider.rs b/crates/client/frontend/cli/src/input/provider.rs similarity index 100% rename from crates/client/cli/src/input/provider.rs rename to crates/client/frontend/cli/src/input/provider.rs diff --git a/crates/client/frontend/cli/src/lib.rs b/crates/client/frontend/cli/src/lib.rs new file mode 100644 index 0000000..306084f --- /dev/null +++ b/crates/client/frontend/cli/src/lib.rs @@ -0,0 +1,28 @@ +//! Terminal UI frontend for Dungeon game. +//! +//! This crate provides a terminal-based user interface for the game. +//! It implements the `dungeon_client::Frontend` trait for pure UI rendering. +//! +//! # Architecture +//! +//! CliFrontend is a pure UI layer that: +//! - Receives a RuntimeHandle for communication +//! - Does NOT own the Runtime +//! - Subscribes to events and submits actions via the handle + +mod app; +mod config; +mod cursor; +mod event; +mod input; +pub mod logging; +pub mod presentation; +mod start_screen; +mod state; + +pub use app::CliFrontend; +pub use config::CliConfig; +pub use start_screen::{StartChoice, show_start_screen}; + +// Re-export for convenience (used in main.rs) +pub use client_frontend_core::FrontendConfig; diff --git a/crates/client/cli/src/main.rs b/crates/client/frontend/cli/src/logging.rs similarity index 67% rename from crates/client/cli/src/main.rs rename to crates/client/frontend/cli/src/logging.rs index d6e4de9..8f2943e 100644 --- a/crates/client/cli/src/main.rs +++ b/crates/client/frontend/cli/src/logging.rs @@ -1,44 +1,18 @@ -//! Terminal client entry point. -mod app; -mod config; -mod cursor; -mod event; -mod input; -mod presentation; -mod state; +//! Logging setup utilities for CLI. use anyhow::Result; -use app::CliApp; -use client_bootstrap::ClientConfig; -use client_core::frontend::FrontendApp; +use std::path::PathBuf; +use std::time::{SystemTime, UNIX_EPOCH}; use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::util::SubscriberInitExt; -#[tokio::main] -async fn main() -> Result<()> { - // Load .env file if it exists (silently ignore if not found) - let _ = dotenvy::dotenv(); - - let client_config = ClientConfig::from_env(); - let cli_config = config::CliConfig::from_env(); - - // Setup logging: both to stderr and to file - setup_logging(&client_config.session_id)?; - - CliApp::builder(client_config, cli_config) - .build() - .await? - .run() - .await -} - -/// Setup logging to both stderr and file -fn setup_logging(session_id: &Option) -> Result<()> { - use std::time::{SystemTime, UNIX_EPOCH}; - - // Determine log directory based on OS - let log_dir = get_log_directory(); - +/// Setup logging to file. +/// +/// Logs are written to platform-specific directories: +/// - macOS: ~/Library/Caches/dungeon/logs/ +/// - Linux: ~/.cache/dungeon/logs/ +/// - Windows: %LOCALAPPDATA%\dungeon\logs\ +pub fn setup_logging(session_id: &Option) -> Result<()> { // Create session ID if not provided let session_id = session_id.clone().unwrap_or_else(|| { let timestamp = SystemTime::now() @@ -48,6 +22,9 @@ fn setup_logging(session_id: &Option) -> Result<()> { format!("session_{}", timestamp) }); + // Determine log directory based on OS + let log_dir = get_log_directory(); + // Create session-specific log directory let session_log_dir = log_dir.join(&session_id); std::fs::create_dir_all(&session_log_dir)?; @@ -80,12 +57,12 @@ fn setup_logging(session_id: &Option) -> Result<()> { Ok(()) } -/// Get the platform-specific log directory -fn get_log_directory() -> std::path::PathBuf { +/// Get the platform-specific log directory. +fn get_log_directory() -> PathBuf { #[cfg(target_os = "macos")] { if let Some(home) = std::env::var_os("HOME") { - let mut path = std::path::PathBuf::from(home); + let mut path = PathBuf::from(home); path.push("Library"); path.push("Caches"); path.push("dungeon"); @@ -97,12 +74,12 @@ fn get_log_directory() -> std::path::PathBuf { #[cfg(target_os = "linux")] { if let Some(xdg_cache) = std::env::var_os("XDG_CACHE_HOME") { - let mut path = std::path::PathBuf::from(xdg_cache); + let mut path = PathBuf::from(xdg_cache); path.push("dungeon"); path.push("logs"); return path; } else if let Some(home) = std::env::var_os("HOME") { - let mut path = std::path::PathBuf::from(home); + let mut path = PathBuf::from(home); path.push(".cache"); path.push("dungeon"); path.push("logs"); @@ -113,7 +90,7 @@ fn get_log_directory() -> std::path::PathBuf { #[cfg(target_os = "windows")] { if let Some(local_appdata) = std::env::var_os("LOCALAPPDATA") { - let mut path = std::path::PathBuf::from(local_appdata); + let mut path = PathBuf::from(local_appdata); path.push("dungeon"); path.push("logs"); return path; @@ -121,5 +98,5 @@ fn get_log_directory() -> std::path::PathBuf { } // Fallback - std::path::PathBuf::from("/tmp/dungeon/logs") + PathBuf::from("/tmp/dungeon/logs") } diff --git a/crates/client/cli/src/presentation/mod.rs b/crates/client/frontend/cli/src/presentation/mod.rs similarity index 100% rename from crates/client/cli/src/presentation/mod.rs rename to crates/client/frontend/cli/src/presentation/mod.rs diff --git a/crates/client/cli/src/presentation/terminal.rs b/crates/client/frontend/cli/src/presentation/terminal.rs similarity index 100% rename from crates/client/cli/src/presentation/terminal.rs rename to crates/client/frontend/cli/src/presentation/terminal.rs diff --git a/crates/client/cli/src/presentation/theme.rs b/crates/client/frontend/cli/src/presentation/theme.rs similarity index 98% rename from crates/client/cli/src/presentation/theme.rs rename to crates/client/frontend/cli/src/presentation/theme.rs index 6cd6f34..898ecab 100644 --- a/crates/client/cli/src/presentation/theme.rs +++ b/crates/client/frontend/cli/src/presentation/theme.rs @@ -3,7 +3,7 @@ //! This module provides concrete styling for the terminal UI, implementing //! the framework-agnostic PresentationMapper trait from client-core. -use client_core::{message::MessageLevel, view_model::PresentationMapper}; +use client_frontend_core::{message::MessageLevel, view_model::PresentationMapper}; use game_core::{PropKind, TerrainKind, stats::StatsSnapshot}; use ratatui::style::{Color, Modifier, Style}; diff --git a/crates/client/frontend/cli/src/presentation/ui.rs b/crates/client/frontend/cli/src/presentation/ui.rs new file mode 100644 index 0000000..a3f09f0 --- /dev/null +++ b/crates/client/frontend/cli/src/presentation/ui.rs @@ -0,0 +1,174 @@ +//! UI rendering using new widget architecture with ViewModel. +//! +//! This module provides the main render entry point that composes all widgets +//! to create the complete terminal UI. +use anyhow::Result; +use game_core::env::MapOracle; +use ratatui::layout::{Alignment, Constraint, Direction, Layout}; + +use crate::{ + presentation::{terminal::Tui, theme::RatatuiTheme, widgets}, + state::{ActionSlots, AppMode, AppState}, +}; +use client_frontend_core::{message::MessageLog, view_model::ViewModel}; + +/// Rendering context containing all state and configuration needed for UI rendering. +pub struct RenderContext<'a> { + pub view_model: &'a ViewModel, + pub messages: &'a MessageLog, + pub app_state: &'a AppState, + pub action_slots: &'a ActionSlots, + pub available_actions: &'a [game_core::ActionKind], + pub message_panel_height: u16, + pub map: &'a dyn MapOracle, +} + +/// Render the terminal UI using ViewModel and widget system. +/// +/// This function routes rendering based on the current app mode: +/// - **Full-screen modes**: Completely replace the game UI (SaveMenu, Inventory, etc.) +/// - **Overlay modes**: Render game UI with a modal on top (AbilityMenu) +/// - **Standard modes**: Render normal game UI (Normal, Examine, Targeting) +/// +/// All widgets consume ViewModel directly with no adapter layers. +pub fn render_with_view_model(terminal: &mut Tui, ctx: &RenderContext) -> Result<()> { + let theme = RatatuiTheme; + + terminal.draw(|frame| { + // Route to full-screen modes first + if ctx.app_state.mode.is_fullscreen() { + render_fullscreen_mode(frame, ctx); + return; + } + + // Otherwise render standard game UI + render_game_ui(frame, ctx, &theme); + + // Apply overlays on top of game UI + if ctx.app_state.mode.is_overlay() { + render_overlay_mode(frame, ctx); + } + })?; + + Ok(()) +} + +/// Render full-screen mode UI (replaces game view entirely). +fn render_fullscreen_mode(frame: &mut ratatui::Frame, ctx: &RenderContext) { + match &ctx.app_state.mode { + AppMode::StartScreen(start_state) => { + widgets::start_screen::render_start_screen(frame, frame.area(), start_state); + } + AppMode::SaveMenu(menu_state) => { + widgets::save_menu::render_fullscreen( + frame, + frame.area(), + menu_state, + &ctx.app_state.save_menu_log, + ); + } + AppMode::Inventory => { + // TODO: Implement inventory screen + // For now, show placeholder + let placeholder = ratatui::widgets::Paragraph::new("Inventory (not implemented)") + .alignment(Alignment::Center) + .block( + ratatui::widgets::Block::default() + .borders(ratatui::widgets::Borders::ALL) + .title(" Inventory "), + ); + frame.render_widget(placeholder, frame.area()); + } + _ => { + // Should never reach here due to is_fullscreen() guard + unreachable!("render_fullscreen_mode called with non-fullscreen mode") + } + } +} + +/// Render overlay mode UI (on top of game view). +fn render_overlay_mode(frame: &mut ratatui::Frame, ctx: &RenderContext) { + match ctx.app_state.mode { + AppMode::AbilityMenu => { + // Center the ability menu overlay + let area = centered_rect(60, 80, frame.area()); + widgets::ability_menu::render(frame, area, ctx.available_actions, ctx.action_slots); + } + _ => { + // Should never reach here due to is_overlay() guard + unreachable!("render_overlay_mode called with non-overlay mode") + } + } +} + +/// Render standard game UI (header, game area, messages, action slots, footer). +/// +/// This is the default UI shown during Normal, Examine, and Targeting modes. +fn render_game_ui(frame: &mut ratatui::Frame, ctx: &RenderContext, theme: &RatatuiTheme) { + let chunks = Layout::default() + .direction(Direction::Vertical) + .constraints([ + Constraint::Length(3), // Header + Constraint::Min(0), // Game area + Constraint::Length(ctx.message_panel_height), // Messages + Constraint::Length(3), // Action slots + Constraint::Length(2), // Footer + ]) + .split(frame.area()); + + widgets::header::render(frame, chunks[0], ctx.view_model, ctx.app_state); + + widgets::game_area::render( + frame, + chunks[1], + ctx.view_model, + ctx.app_state, + ctx.map, + theme, + ); + + let recent_messages: Vec<_> = ctx + .messages + .recent(ctx.message_panel_height as usize) + .cloned() + .collect(); + widgets::messages::render( + frame, + chunks[2], + &recent_messages, + ctx.message_panel_height, + theme, + ); + + // Action slots bar + widgets::action_slots::render(frame, chunks[3], ctx.action_slots); + + widgets::footer::render(frame, chunks[4], ctx.app_state); +} + +/// Create a centered rectangle for modal overlays. +fn centered_rect( + percent_x: u16, + percent_y: u16, + r: ratatui::layout::Rect, +) -> ratatui::layout::Rect { + use ratatui::layout::{Constraint, Direction, Layout}; + + let popup_layout = Layout::default() + .direction(Direction::Vertical) + .constraints([ + Constraint::Percentage((100 - percent_y) / 2), + Constraint::Percentage(percent_y), + Constraint::Percentage((100 - percent_y) / 2), + ]) + .split(r); + + Layout::default() + .direction(Direction::Horizontal) + .constraints([ + Constraint::Percentage((100 - percent_x) / 2), + Constraint::Percentage(percent_x), + Constraint::Percentage((100 - percent_x) / 2), + ]) + .split(popup_layout[1])[1] +} diff --git a/crates/client/cli/src/presentation/widgets/ability_menu.rs b/crates/client/frontend/cli/src/presentation/widgets/ability_menu.rs similarity index 100% rename from crates/client/cli/src/presentation/widgets/ability_menu.rs rename to crates/client/frontend/cli/src/presentation/widgets/ability_menu.rs diff --git a/crates/client/cli/src/presentation/widgets/action_slots.rs b/crates/client/frontend/cli/src/presentation/widgets/action_slots.rs similarity index 100% rename from crates/client/cli/src/presentation/widgets/action_slots.rs rename to crates/client/frontend/cli/src/presentation/widgets/action_slots.rs diff --git a/crates/client/cli/src/presentation/widgets/examine.rs b/crates/client/frontend/cli/src/presentation/widgets/examine.rs similarity index 91% rename from crates/client/cli/src/presentation/widgets/examine.rs rename to crates/client/frontend/cli/src/presentation/widgets/examine.rs index ee1cd0a..3d7c5aa 100644 --- a/crates/client/cli/src/presentation/widgets/examine.rs +++ b/crates/client/frontend/cli/src/presentation/widgets/examine.rs @@ -1,6 +1,6 @@ //! Examine widget for detailed entity and tile inspection. -use client_core::view_model::{PresentationMapper, ViewModel, entities::ActorView}; +use client_frontend_core::view_model::{PresentationMapper, ViewModel, entities::ActorView}; use game_core::{EntityId, Position, env::MapOracle}; use ratatui::{ Frame, @@ -43,12 +43,28 @@ pub fn render>( // Determine tile position to display let tile_position = if let Some(entity_id) = ctx.highlighted_entity { - // Show tile info for highlighted entity's position + // Show tile info for highlighted entity's position (try all entity types) view_model .actors .iter() .find(|a| a.id == entity_id) .and_then(|a| a.position) + .or_else(|| { + // Not an actor - try item + view_model + .items + .iter() + .find(|i| i.id == entity_id) + .map(|i| i.position) + }) + .or_else(|| { + // Not an item - try prop + view_model + .props + .iter() + .find(|p| p.id == entity_id) + .map(|p| p.position) + }) .or(ctx.cursor_position) .or(view_model.player.position) .unwrap_or_else(|| game_core::Position::new(0, 0)) @@ -253,7 +269,9 @@ fn render_actor_details<'a, T: PresentationMapper