### Navigate to ValueSetter Module Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/3-quickstart.md This bash command navigates you to the `value-setter` example directory within the Sovereign Rollup Starter repository. ```bash # From the sov-rollup-starter root cd examples/value-setter/ ``` -------------------------------- ### Build and Run the Rollup Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/3-quickstart.md Command to compile and start the Sovereign SDK rollup. This command should be executed from the root directory of the project. ```bash cargo run ``` -------------------------------- ### Install and Serve Sovereign Book Source: https://github.com/sovereign-labs/sovereign-book/blob/main/README.md Instructions to install mdbook and serve the Sovereign SDK book locally. Requires Rust and Cargo. ```shell cargo install mdbook mdbook serve --open ``` -------------------------------- ### Expected Modules Response Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/2-running-starter.md Example JSON response from the /modules endpoint, listing the active modules in the starter rollup. ```json { "data": { "modules": [ "bank", "sequencer_registry", "accounts", "value_setter" // ... and others ] }, "meta": {} } ``` -------------------------------- ### Verify Updated State of Value Setter Module Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/3-quickstart.md Uses `curl` to query the `value-setter` module's state again after submitting the transaction. This verifies that the value has been updated to the new value (99) by the admin. ```bash curl http://127.0.0.1:12346/modules/value-setter/state/value # Expected output: {"value":99} ``` -------------------------------- ### Start Observability Stack Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/6-0-intro.md Starts the Docker containers for the observability stack, including Grafana and InfluxDB, providing instant visibility into rollup metrics. Requires the `rollup-starter` repository. ```bash make start-obs ... Waiting for all services to become healthy... ⏳ Waiting for services... (45 seconds remaining) ✅ All observability services are healthy! 🚀 Observability stack is ready: - Grafana: http://localhost:3000 (admin/admin123) - InfluxDB: http://localhost:8086 (admin/admin123) ``` -------------------------------- ### Query Initial State of Value Setter Module Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/3-quickstart.md Uses `curl` to query the current value stored in the `value-setter` module's state. Initially, the value is expected to be null as only the admin address is set during genesis. ```bash curl http://127.0.0.1:12346/modules/value-setter/state/value # Expected output: {"value":null} ``` -------------------------------- ### Configure Genesis State for Value Setter Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/3-quickstart.md Sets the initial admin address for the `value-setter` module in the genesis configuration file. The SDK deserializes this JSON into the module's configuration struct upon rollup startup. ```json // In sov-rollup-starter/configs/mock_da/genesis.json { // ... other module configs "value_setter": { "admin": "0x9b08ce57a93751aE790698A2C9ebc76A78F23E25" } } ``` -------------------------------- ### Initial ValueSetter Module Structure Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/3-quickstart.md This Rust code defines the basic structure of the ValueSetter module, including its state and the `call` method for updating a value. It currently lacks any access control. ```rust use sov_modules_api::prelude::*; use sov_state::StateValue; #[derive(Clone, ModuleInfo, ModuleRestApi)] pub struct ValueSetter { #[id] pub id: ModuleId, /// Holds the value #[state] pub value: StateValue, } #[derive(Clone, Debug, PartialEq, Eq, JsonSchema, UniversalWallet)] #[serialize(Borsh, Serde)] #[serde(rename_all = "snake_case")] pub enum CallMessage { SetValue(u32), } impl Module for ValueSetter { type Spec = S; type Config = (); // No configuration yet! type CallMessage = CallMessage; type Event = (); // The `call` method handles incoming transactions. // Notice it doesn't check *who* is calling. fn call(&mut self, msg: Self::CallMessage, _context: &Context, state: &mut impl TxState) -> Result<()> { match msg { CallMessage::SetValue(new_value) => { self.value.set(&new_value, state)?; Ok(()) } } } } ``` -------------------------------- ### Sovereign Value Setter Module Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/4-6-prebuilt-modules.md A basic example module intended for educational purposes within the Sovereign SDK documentation. It serves as a foundational example for understanding module development. ```rust crates/module-system/module-implementations/sov-value-setter ``` -------------------------------- ### Merkle Tree Layout Example Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/7-2-abstractions.md Illustrates the key generation strategy for module state within the Jellyfish Merkle Tree, showing how StateValue, StateMap, and StateVec entries are mapped to unique paths. ```rust // Suppose we're in the file my_crate/lib.rs #[derive(ModuleInfo, Clone)] pub struct Example { #[id] pub(crate) id: ModuleId, #[state] pub(crate) some_value: sov_modules_api::StateValue, #[state] pub(crate) some_vec: sov_modules_api::StateVec, #[state] pub(crate) some_map: sov_modules_api::StateMap, } // The value of `some_value` would be stored at the path // `hash(b"my_crate/Example/some_value")`. // The value of the key "hello" in `some_map` would be stored at // `hash(b"my_crate/Example/some_map/\xe2\x81\x80hello")` (where `\xe2\x81\x80hello` represents the borsh encoding of the string "hello") etc. ``` -------------------------------- ### Setup Helper Function for Module Testing Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/4-2-testing-your-module.md A helper function to set up the test environment, including creating test users, configuring the genesis state, and initializing the TestRunner. It simplifies test case creation by handling boilerplate code. Dependencies: `sov-test-utils`, `sov-modules-api`. ```rust use sov_test_utils::runtime::genesis::optimistic::HighLevelOptimisticGenesisConfig; use sov_test_utils::runtime::TestRunner; use sov_test_utils::TestUser; // A helper struct to hold our test users, for convenience. pub struct TestData { pub admin: TestUser, pub regular_user: TestUser, } pub fn setup() -> (TestData, TestRunner, S>) { // Create two users, the first of which will be our admin. // (The `HighLevelOptimisticGenesisConfig` builder is a convenient way // to set up the initial state for core modules.) let genesis_config = HighLevelOptimisticGenesisConfig::generate() .add_accounts_with_default_balance(2); let mut users = genesis_config.additional_accounts().to_vec(); let regular_user = users.pop().unwrap(); let admin = users.pop().unwrap(); let test_data = TestData { admin: admin.clone(), regular_user, }; // Configure the genesis state for our ValueSetter module. let value_setter_config = ValueSetterConfig { admin: admin.address(), }; // Build the final genesis config by combining // the core config with our module's specific config. let genesis = GenesisConfig::from_minimal_config( genesis_config.into(), value_setter_config, ); // Initialize the TestRunner with the genesis state. // The runner gives us a simple way to execute transactions and query state. let runner = TestRunner::new_with_genesis( genesis.into_genesis_params(), TestRuntime::default(), ); (test_data, runner) } ``` -------------------------------- ### Add Admin Check to Call Method Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/3-quickstart.md Modifies the `call` method in the `value-setter` module to ensure only the designated admin address can set a new value. It reads the admin address from state and compares it with the transaction sender's address. ```rust // In examples/value-setter/src/lib.rs // ... existing code ... fn call(&mut self, msg: Self::CallMessage, context: &Context, state: &mut impl TxState) -> Result<()> { match msg { CallMessage::SetValue(new_value) => { // Read the admin's address from state. let admin = self.admin.get_or_err(state)?; // Ensure the sender is the admin. anyhow::ensure!(admin == *context.sender(), "Only the admin can set the value."); // If the check passes, update the state. self.value.set(&new_value, state)?; Ok(()) } } } } ``` -------------------------------- ### Initialize Admin in Genesis and Update Module Config Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/3-quickstart.md This Rust code updates the `Module` implementation for `ValueSetter`. It sets the `Config` type to `ValueSetterConfig` and implements the `genesis` method to initialize the `admin` state variable using the provided configuration. The `call` method signature is also shown, indicating where future checks will be placed. ```rust // In examples/value-setter/src/lib.rs // ... existing code ... impl Module for ValueSetter { type Spec = S; type Config = ValueSetterConfig; // Use the new config struct type CallMessage = CallMessage; type Event = (); // `genesis` initializes the module's state. Here, we set the admin address. fn genesis(&mut self, _header: &::BlockHeader, config: &Self::Config, state: &mut impl GenesisState) -> Result<()> { self.admin.set(&config.admin, state)?; Ok(()) } fn call(&mut self, msg: Self::CallMessage, context: &Context, state: &mut impl TxState) -> Result<()> { // ... existing code ... } ``` -------------------------------- ### Define Configuration Struct for Admin Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/3-quickstart.md This Rust code defines a `ValueSetterConfig` struct, which includes an `admin` field of type `S::Address`. This struct is used to configure the module at genesis, allowing the admin address to be set via `genesis.json`. ```rust // In examples/value-setter/src/lib.rs // Add the module's configuration, read from genesis.json #[derive(Clone, Debug, PartialEq, Eq)] #[serialize(Serde)] #[serde(rename_all = "snake_case")] pub struct ValueSetterConfig { pub admin: S::Address, } ``` -------------------------------- ### Add Admin State Variable Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/3-quickstart.md This Rust code snippet demonstrates how to add a new state variable named `admin` to the `ValueSetter` struct. This variable will store the address of the administrator, marked with the `#[state]` attribute. ```rust // In examples/value-setter/src/lib.rs #[derive(Clone, ModuleInfo, ModuleRestApi)] pub struct ValueSetter { // ... existing code ... /// The new state value to hold the address of the admin. #[state] pub admin: StateValue, } ``` -------------------------------- ### Update Value Setter Module via Transaction Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/3-quickstart.md Modifies the JavaScript client script to send a transaction that calls the `set_value` method of the `value-setter` module. This transaction is sent from the admin address configured in the genesis state. ```typescript // In sov-rollup-starter/examples/starter-js/src/index.ts // Replace the existing call message with this one: const callMessage: RuntimeCall = { value_setter: { // The module's name in the Runtime struct set_value: 99, // The CallMessage variant (in snake_case) and its new value }, }; // From the sov-rollup-starter/examples/starter-js directory npm install npm run start ``` -------------------------------- ### Setting Log Levels via Environment Variable Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/6-2-logging.md Provides an example of how to configure log levels for a Rust application using the `RUST_LOG` environment variable. This allows dynamic control over logging verbosity. ```bash RUST_LOG=info,my_module=debug cargo run ``` -------------------------------- ### Clone and Run Starter Rollup Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/2-running-starter.md Commands to clone the starter rollup repository and build/run the rollup node using Cargo. ```bash git clone https://github.com/Sovereign-Labs/rollup-starter.git cd rollup-starter cargo run ``` -------------------------------- ### Sovereign Module Template Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/4-6-prebuilt-modules.md Provides a starter template that demonstrates best practices for structuring Sovereign SDK modules. It includes guidance on state management, calls, and event handling. ```rust crates/module-system/module-implementations/module-template ``` -------------------------------- ### Sovereign SDK - Full Node Implementation Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/1-intro.md The Sovereign SDK provides a complete, production-ready full-node implementation out-of-the-box. This includes a sequencer with automatic failover, REST and WebSocket APIs for interaction, an indexer for querying data, and auto-generated OpenAPI specifications for API documentation. Developers can write their business logic in standard Rust and build this comprehensive node with a simple `cargo build` command. ```rust cargo build ``` -------------------------------- ### Sovereign SDK RuntimeCall Example Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/4-3-wallets-and-accounts.md Demonstrates a JavaScript object representing a RuntimeCall variant, which is a core part of the custom transaction format in Sovereign SDK rollups. This object is serialized into a compact binary format for signing. ```typescript const call = { value_setter: { set_value: 99, }, }; ``` -------------------------------- ### Rust Toolchain Configuration Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/2-running-starter.md Indicates that the starter repository uses a rust-toolchain.toml file to manage Rust toolchain versions, ensuring compatibility. ```rust # This file is managed by rustup and specifies the toolchain to use. # For example: stable-x86_64-unknown-linux-gnu # Or a specific version: 1.60.0 [toolchain] channel = "1.88" ``` -------------------------------- ### Running Sovereign SDK Tests Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/4-2-testing-your-module.md Instructions on how to execute the tests written for your Sovereign SDK module using the standard Cargo test command. ```bash cargo test ``` -------------------------------- ### EIP-712 Standard for Structured Data Signing Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/4-3-wallets-and-accounts.md Illustrates the concept of EIP-712, an Ethereum standard for signing typed, structured data. This standard allows wallets to present transaction details in a human-readable format, enhancing security and user experience. The example references a visual representation in MetaMask. ```APIDOC EIP-712 Standard: - Signs typed, structured data. - Enhances security by displaying human-readable transaction details in wallets. - Example visual in MetaMask: ![A message signing request from Hyperliquid](/assets/message-signing.png) - Future support for Sovereign SDK rollups planned. ``` -------------------------------- ### Verify Rollup Node Modules Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/2-running-starter.md Uses curl to query the /modules endpoint of a running rollup node to verify its active components. ```bash curl 'http://127.0.0.1:12346/modules' ``` -------------------------------- ### Add Revenue Share Module Reference Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/8-0-complying-with-revenue-share.md Demonstrates how to add the `sov-revenue-share` module to your application's module structure. This is a prerequisite for utilizing the revenue sharing functionality. ```rust #[derive(Clone, ModuleInfo, ModuleRestApi)] pub struct YourApp { #[id] pub id: ModuleId, #[module] pub revenue_share: sov_revenue_share::RevenueShare, // ... other modules } ``` -------------------------------- ### Sovereign Revenue Share Module Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/4-6-prebuilt-modules.md Automates on-chain fee sharing for the utilization of premium Sovereign SDK components, such as the low-latency sequencer. This facilitates a sustainable ecosystem. ```rust crates/module-system/module-implementations/sov-revenue-share ``` -------------------------------- ### Basic Logging Patterns Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/6-2-logging.md Demonstrates basic logging within a Rust module using the `tracing::trace!` macro. Logs are emitted immediately and are not rolled back on transaction revert, aiding in debugging failed transactions. ```rust use tracing::trace; impl MyModule { pub(crate) fn freeze( &mut self, token_id: TokenId, context: &Context, state: &mut impl TxState, ) -> Result<()> { // Logging at the start of operation trace!(freezer = %sender, "Freeze token request"); // Redundant code elided here... token .freeze(sender) .with_context(|| format!("Failed to freeze token_id={}", &token_id))?; self.tokens.set(&token_id, &token, state)?; // Logging at the end of operation trace!( freezer = %sender, %token_id, "Successfully froze tokens" ); Ok(()) } } ``` -------------------------------- ### Sovereign Prover Incentives Module Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/4-6-prebuilt-modules.md Manages prover registration, proof validation, and rewards distribution within the Sovereign SDK. This module is crucial for incentivizing honest behavior from provers. ```rust crates/module-system/module-implementations/sov-prover-incentives ``` -------------------------------- ### State Access Optimization: Bundling Related Data Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/4-5-performance.md Demonstrates the anti-pattern of separate state item accesses versus the recommended pattern of bundling related data into a single `StateValue` for improved performance by reducing Merkle proof generation costs. ```rust // ANTI-PATTERN: Separated state items #[state] pub usernames: StateMap, #[state] pub bios: StateMap, #[state] pub follower_counts: StateMap, ``` ```rust // GOOD PATTERN: Bundled state pub struct ProfileData { pub username: String, pub bio: String, pub follower_count: u64, } #[state] pub profiles: StateMap, ``` -------------------------------- ### Sovereign Book Deployment Source: https://github.com/sovereign-labs/sovereign-book/blob/main/README.md The deployment process for the Sovereign SDK book is triggered by merging changes to the main branch. ```shell Just merge to main. ``` -------------------------------- ### Sovereign SDK Sequencer Registry Module Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/4-6-prebuilt-modules.md The Sequencer Registry module manages sequencer registration, bonding, and rewards distribution, supporting decentralized sequencing. This is a rollup economics module. ```rust /// Manages sequencer registration, bonding, and rewards distribution. /// /// # Dependencies /// - Requires mechanisms for managing sequencer state and reward distribution. /// /// # Usage /// ```rust /// // Example usage within a Sovereign SDK context (conceptual) /// // let sequencer_registry = SovSequencerRegistry::new(); /// // sequencer_registry.register_sequencer(...); /// // sequencer_registry.distribute_rewards(...); /// ``` pub struct SovSequencerRegistry; impl SovSequencerRegistry { /// Creates a new instance of the Sequencer Registry module. pub fn new() -> Self { Self } // Placeholder for registering a sequencer // pub fn register_sequencer(&self, sequencer_address: Address, bond_amount: u256) { ... } // Placeholder for distributing rewards to sequencers // pub fn distribute_rewards(&self, block_number: u64) { ... } } ``` -------------------------------- ### Sovereign Attester Incentives Module Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/4-6-prebuilt-modules.md Handles the attestation and challenge process for optimistic rollups. It manages prover bonding and rewards distribution, ensuring the integrity of the rollup. ```rust crates/module-system/module-implementations/sov-attester-incentives ``` -------------------------------- ### Sovereign SDK - API Documentation Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/1-intro.md The Sovereign SDK automatically generates OpenAPI specifications for its REST and WebSocket APIs. This allows for easy integration and understanding of the available endpoints and data structures. The generated documentation provides details on methods, parameters, and return values, facilitating client development. ```APIDOC OpenAPI Specifications: - Auto-generated for REST & WebSocket APIs - Provides details on endpoints, methods, parameters, and return values - Facilitates client development and integration ``` -------------------------------- ### Sovereign Book Structure and Theming Source: https://github.com/sovereign-labs/sovereign-book/blob/main/README.md Guidance on editing the Sovereign SDK book's content, structure, and theme. Content is in Markdown files, structure in SUMMARY.md, and theme in theme/variables.css. ```markdown To edit an existing chapter, simply modify the corresponding Markdown file in the `src` directory. To change the book structure, modify `SUMMARY.md`. To edit the default theme, modify `theme/variables.css`. ``` -------------------------------- ### Sovereign SDK Accounts Module Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/4-6-prebuilt-modules.md The Accounts module manages user accounts, public keys, and nonces. This is a core infrastructure module. ```rust /// Manages user accounts, public keys, and nonces. /// /// # Dependencies /// - Requires access to persistent storage for account data. /// /// # Usage /// ```rust /// // Example usage within a Sovereign SDK context (conceptual) /// // let accounts_module = SovAccounts::new(); /// // accounts_module.get_account(...); /// // accounts_module.create_account(...); /// ``` pub struct SovAccounts; impl SovAccounts { /// Creates a new instance of the Accounts module. pub fn new() -> Self { Self } // Placeholder for retrieving account information // pub fn get_account(&self, address: Address) -> Option { ... } // Placeholder for creating a new account // pub fn create_account(&self, address: Address, initial_nonce: u64) { ... } } ``` -------------------------------- ### Structured vs. Unstructured Logging Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/6-2-logging.md Demonstrates the difference between structured logging with key-value pairs for better filtering and unstructured string interpolation. Structured logging is preferred for clarity and searchability. ```rust debug!(user = %address, action = "deposit", amount = %value, "Processing deposit"); // Avoid - unstructured string interpolation debug!("Processing deposit for {} of amount {}", address, value); ``` -------------------------------- ### State Management with StateMap, StateValue, StateVec Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/7-2-abstractions.md Provides an overview of how to use StateMap, StateValue, and StateVec for managing module state, including accessing and modifying values through TxState and the importance of serialization. ```APIDOC StateMap: - Maps keys of type K to values of type V. - Requires K and V to be serializable. - Keys are appended to the module's prefix path. - Example: `sov_modules_api::StateMap>` StateValue: - Stores a single value of type V. - Requires V to be serializable. - Stored at a unique path derived from the field name. - Example: `sov_modules_api::StateValue` StateVec: - Stores a vector of values of type V. - Requires V to be serializable. - Indices are appended to the module's prefix path. - Example: `sov_modules_api::StateVec` Accessing and Modifying State: - Use `TxState` to interact with state values. - Fetch value: `state_value.get(&mut state)` - Update value: `state_value.set(new_value, &mut working_set)` - Modifications are not persistent unless `set` is called. ``` -------------------------------- ### Secp256k1Signer Initialization and Usage Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/4-3-wallets-and-accounts.md Shows how to initialize and use the Secp256k1Signer from the Sovereign web3.js library for programmatic transaction signing. This signer is suitable for developers, scripting, and backend services that have direct access to a private key. ```typescript import { Secp256k1Signer } from "@sovereign-labs/signers"; // Initialize with a raw private key const privKey = "0d87c12ea7c12024b3f70a26d735874608f17c8bce2b48e6fe87389310191264"; const signer = new Secp256k1Signer(privKey); // Use the signer to send a transaction await rollup.call(callMessage, { signer }); ``` -------------------------------- ### Sovereign SDK EVM Module Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/4-6-prebuilt-modules.md The EVM module offers an EVM compatibility layer, executing standard, RLP-encoded Ethereum transactions. This is a user-facing module. ```rust /// Provides an EVM compatibility layer. /// /// # Dependencies /// - Relies on an underlying EVM runtime environment. /// /// # Usage /// ```rust /// // Example usage within a Sovereign SDK context (conceptual) /// // let evm_module = SovEVM::new(); /// // evm_module.execute_transaction(...); /// ``` pub struct SovEVM; impl SovEVM { /// Creates a new instance of the EVM module. pub fn new() -> Self { Self } // Placeholder for EVM transaction execution // pub fn execute_transaction(&self, rlp_encoded_tx: Vec) -> TransactionResult { ... } } ``` -------------------------------- ### Sovereign SDK Blob Storage Module Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/4-6-prebuilt-modules.md The Blob Storage module is a deferred blob storage system that enables soft-confirmations without compromising censorship resistance. This is a core infrastructure module. ```rust /// Implements a deferred blob storage system. /// /// # Dependencies /// - Requires a mechanism for deferring and retrieving blobs. /// /// # Usage /// ```rust /// // Example usage within a Sovereign SDK context (conceptual) /// // let blob_storage_module = SovBlobStorage::new(); /// // blob_storage_module.store_blob(...); /// // blob_storage_module.get_blob(...); /// ``` pub struct SovBlobStorage; impl SovBlobStorage { /// Creates a new instance of the Blob Storage module. pub fn new() -> Self { Self } // Placeholder for storing a blob // pub fn store_blob(&self, data: Vec, commitment: BlobCommitment) { ... } // Placeholder for retrieving a blob // pub fn get_blob(&self, commitment: BlobCommitment) -> Option> { ... } } ``` -------------------------------- ### Sovereign SDK Module Structure Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/4-1-anatomy-of-a-module.md Outlines the fundamental traits and methods required for a Sovereign SDK module, including configuration, genesis, and call handling. ```APIDOC Module Trait: - Defines the core interface for a Sovereign SDK module. - Key associated types: - `Spec`: The specification for the runtime environment. - `Config`: The configuration structure for the module, loaded from genesis. - `CallMessage`: An enum representing the public actions users can perform. - `Event`: An enum representing events emitted by the module. Methods: - `genesis(header, config, state)`: - Initializes the module's state using the provided configuration. - Executed once when the rollup is first deployed. - Parameters: - `header`: Block header from the Data Availability layer. - `config`: Module-specific configuration. - `state`: Mutable reference to the module's state. - Returns: `Result<()>` indicating success or failure. - `call(msg, context, state)`: - Entry point for handling user-defined messages (actions). - Parameters: - `msg`: The `CallMessage` to be processed. - `context`: Context containing metadata like sender address. - `state`: Mutable reference to the module's state. - Returns: `Result<()>` indicating success or failure. Reverts state on `Err`. Error Handling: - Use `anyhow::ensure!` for predictable user errors. - Unrecoverable system errors should cause a `panic!`. - Transaction execution and event emission are atomic; reverts are guaranteed. Generics and Schemars: - If `CallMessage` or `Event` are generic over `S: Spec`: - Add `#[schemars(bound = "S: Spec", rename = "MyEnum")]` attribute to the enum. - This helps `schemars` generate correct JSON schemas for the module's API. Security Considerations: - Use `SafeVector` and `SafeString` for fields deserialized directly into `CallMessage` to prevent DoS attacks by limiting payload size. ``` -------------------------------- ### Sovereign SDK Paymaster Module Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/4-6-prebuilt-modules.md The Paymaster module enables gas sponsorship for meta-transactions, allowing users to transact without holding native gas tokens. This is a user-facing module. ```rust /// Enables gas sponsorship (meta-transactions). /// /// # Dependencies /// - Relies on the core SDK context for transaction processing and fee management. /// /// # Usage /// ```rust /// // Example usage within a Sovereign SDK context (conceptual) /// // let paymaster_module = SovPaymaster::new(); /// // paymaster_module.sponsor_transaction(...); /// ``` pub struct SovPaymaster; impl SovPaymaster { /// Creates a new instance of the Paymaster module. pub fn new() -> Self { Self } // Placeholder for transaction sponsorship logic // pub fn sponsor_transaction(&self, transaction: Transaction, sponsor_key: PrivateKey) { ... } } ``` -------------------------------- ### Deriving ModuleInfo with Macro Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/7-2-abstractions.md Demonstrates how to automatically derive the ModuleInfo trait for a module using a procedural macro, simplifying ID generation and state prefixing. ```rust #[derive(ModuleInfo, Clone)] pub struct Bank { /// The id of the sov-bank module. #[id] pub(crate) id: ModuleId, /// The gas configuration of the sov-bank module. #[gas] pub(crate) gas: BankGasConfig, /// A mapping of [`TokenId`]s to tokens in the sov-bank. #[state] pub(crate) tokens: sov_modules_api::StateMap>, } ``` -------------------------------- ### Native vs. ZK Execution in Sovereign SDK Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/7-2-abstractions.md Explains the fundamental difference between 'native' code execution for full nodes and zero-knowledge execution for ZK proofs. Native execution allows full system access (network, disk), while ZK execution restricts these, relying on special syscalls and potentially untrusted prover data. The 'native' cargo feature gates code specific to full node operations. ```rust // Example of a concept related to native vs ZK execution // In native mode, you might access the network directly: // fn fetch_data_from_network(url: &str) -> Result, Error> { ... } // In ZK mode, network access is simulated via syscalls: // fn zk_syscall_network_read(request_data: &[u8]) -> Vec { ... } // Code gated behind the 'native' feature: #[cfg(feature = "native")] mod native_only { // RPC implementations, data pre-processing for ZK verification } ``` -------------------------------- ### Sovereign SDK Runtime Structure Source: https://github.com/sovereign-labs/sovereign-book/blob/main/src/7-2-abstractions.md Defines the structure of a Runtime in the Sovereign SDK, which serves as the core of a sov-modules rollup. It includes essential modules like Bank, Sequencer Registry, Prover Incentives, Accounts, NFT, and EVM, all generic over a `Spec` trait for customization. ```rust pub struct Runtime { /// The Bank module implements fungible tokens, which are needed to charge `gas` pub bank: sov_bank::Bank, /// The Sequencer Registry module is where we track which addresses can send batches to the rollup pub sequencer_registry: sov_sequencer_registry::SequencerRegistry, /// The Prover Incentives module is where we reward provers who do useful work pub prover_incentives: sov_prover_incentives::ProverIncentives, /// The Accounts module implements identities on the rollup. All of the other modules rely on it /// to link cryptographic keys to logical accounts pub accounts: sov_accounts::Accounts, /// The NFT module provides an implementation of a non-fungible token standard. It's totally optional. pub nft: sov_nft_module::NonFungibleToken, #[cfg_attr(feature = "native", cli_skip)] /// The EVM module lets the rollup run Ethereum smart contracts. It's totally optional. pub evm: sov_evm::Evm, } ```