- Overview
- System Architecture
- Directory Structure
- Core Components
- Data Flow
- Module Descriptions
- Design Patterns
- Extension Points
StarForge is a command-line interface (CLI) tool built in Rust for Stellar and Soroban blockchain development. It provides a comprehensive suite of tools for wallet management, contract development, deployment, and testing.
- Modularity: Clear separation between commands, utilities, and plugins
- Type Safety: Leveraging Rust's type system for reliability
- Extensibility: Plugin system for third-party extensions
- User Experience: Colored output, progress indicators, and helpful error messages
- Security: Encrypted key storage, hardware wallet support, validation at every step
- Language: Rust 1.80+
- CLI Framework: clap 4.4.18 (derive API)
- Cryptography: ed25519-dalek, aes-gcm, argon2
- Blockchain: stellar-strkey, stellar-xdr
- HTTP: ureq 2.7.1
- Serialization: serde, toml, serde_json
- UI: colored, indicatif, dialoguer
┌─────────────────────────────────────────────────────────────┐
│ User CLI │
└─────────────────────┬───────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Main Entry Point │
│ (src/main.rs) │
│ - Command parsing (clap) │
│ - Banner display │
│ - Command routing │
│ - Telemetry tracking │
└─────────────────────┬───────────────────────────────────────┘
│
┌─────────────┴─────────────┐
▼ ▼
┌──────────────────┐ ┌──────────────────┐
│ Commands │ │ Utilities │
│ (src/commands/) │◄────►│ (src/utils/) │
└────────┬─────────┘ └──────────────────┘
│ │
│ ├─ Config Management
│ ├─ Cryptography
│ ├─ Horizon API
│ ├─ Soroban RPC
│ ├─ Template System
│ └─ Print Utilities
│
├─ Wallet Management
├─ Contract Operations
├─ Network Management
├─ Transaction Handling
├─ Template Marketplace
└─ Plugin System
│
▼
┌─────────────────────────────────────────────────────────────┐
│ External Systems │
│ - Stellar Horizon API │
│ - Soroban RPC │
│ - Git Repositories │
│ - Hardware Wallets (Ledger/Trezor) │
│ - File System (~/.starforge/) │
└─────────────────────────────────────────────────────────────┘
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Wallet │────►│ Config │◄────│ Network │
│ Commands │ │ Utils │ │ Commands │
└──────────┘ └────┬─────┘ └──────────┘
│
▼
┌──────────┐
│ Horizon │
│ API │
└──────────┘
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Contract │────►│ Soroban │◄────│ Deploy │
│ Commands │ │ RPC │ │ Commands │
└──────────┘ └──────────┘ └──────────┘
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Template │────►│ Template │◄────│ New │
│ Commands │ │ Utils │ │ Commands │
└──────────┘ └──────────┘ └──────────┘
starforge/
├── src/
│ ├── main.rs # Entry point, CLI setup, command routing
│ ├── commands/ # Command implementations
│ │ ├── mod.rs # Module exports
│ │ ├── wallet.rs # Wallet management (create, list, show, fund)
│ │ ├── new.rs # Project scaffolding
│ │ ├── contract.rs # Contract operations (inspect, invoke)
│ │ ├── deploy.rs # Contract deployment
│ │ ├── network.rs # Network management
│ │ ├── tx.rs # Transaction operations
│ │ ├── template.rs # Template marketplace
│ │ ├── plugin.rs # Plugin management
│ │ ├── monitor.rs # Real-time monitoring
│ │ ├── shell.rs # Interactive REPL
│ │ ├── test.rs # Contract testing
│ │ ├── gas.rs # Gas analysis
│ │ ├── benchmark.rs # Performance benchmarking
│ │ ├── tutorial.rs # Interactive tutorials
│ │ ├── completions.rs # Shell completions
│ │ ├── invoke.rs # Contract invocation
│ │ └── info.rs # System information
│ ├── utils/ # Utility modules
│ │ ├── mod.rs # Module exports
│ │ ├── config.rs # Configuration management
│ │ ├── crypto.rs # Encryption/decryption
│ │ ├── horizon.rs # Horizon API client
│ │ ├── soroban.rs # Soroban RPC client
│ │ ├── templates.rs # Template system
│ │ ├── print.rs # Terminal output utilities
│ │ ├── hardware_wallet.rs # Hardware wallet integration
│ │ ├── multisig.rs # Multi-signature support
│ │ ├── notifications.rs # User notifications
│ │ ├── optimizer.rs # WASM optimization
│ │ ├── profiler.rs # Performance profiling
│ │ ├── repl.rs # REPL implementation
│ │ ├── sandbox.rs # Local contract execution
│ │ ├── stream.rs # Event streaming
│ │ ├── telemetry.rs # Usage analytics
│ │ ├── test_runner.rs # Test execution
│ │ ├── tutorial_engine.rs # Tutorial system
│ │ └── mock_soroban.rs # Mock Soroban for testing
│ └── plugins/ # Plugin system
│ ├── mod.rs # Module exports
│ ├── interface.rs # Plugin trait definitions
│ ├── loader.rs # Dynamic library loading
│ └── registry.rs # Plugin registry
├── templates/ # Template marketplace
│ ├── registry.json # Template metadata
│ ├── README.md # Template documentation
│ └── examples/ # Example templates
│ └── simple-counter/ # Counter contract template
├── tutorials/ # Interactive tutorials
│ └── hello-world/ # Hello world tutorial
├── benches/ # Performance benchmarks
│ └── benchmarks.rs # Criterion benchmarks
├── tests/ # Integration tests
│ └── template_marketplace_test.rs
├── examples/ # Usage examples
│ └── template_marketplace_usage.md
├── Cargo.toml # Rust package manifest
├── build.rs # Build script (completions)
├── Dockerfile # Container image
├── docker-compose.yml # Docker composition
└── Documentation files
├── README.md # Main documentation
├── Documentation.md # Extended documentation
├── ARCHITECTURE.md # This file
├── TEMPLATE_MARKETPLACE.md # Template feature docs
├── QUICK_START_TEMPLATES.md # Quick start guide
└── IMPLEMENTATION_SUMMARY.md # Implementation details
Purpose: Application bootstrap and command routing
Responsibilities:
- Parse command-line arguments using clap
- Display ASCII banner (unless
--quiet) - Route commands to appropriate handlers
- Track telemetry for usage analytics
- Handle errors and exit codes
Key Code Flow:
fn main() {
let cli = Cli::parse(); // Parse CLI args
print_banner(); // Show banner
let result = match cli.command { // Route to handler
Commands::Wallet(cmd) => commands::wallet::handle(cmd),
Commands::Template(cmd) => commands::template::handle(cmd),
// ... other commands
};
track_telemetry(); // Log usage
handle_error(result); // Exit with code
}Purpose: Implement user-facing commands
Pattern: Each command module follows this structure:
// Command definition with clap
#[derive(Subcommand)]
pub enum CommandName {
SubCommand { /* args */ },
}
// Main handler
pub fn handle(cmd: CommandName) -> Result<()> {
match cmd {
SubCommand::Action { args } => action(args),
}
}
// Individual action handlers
fn action(args: Args) -> Result<()> {
// 1. Validate inputs
// 2. Load configuration
// 3. Call utility functions
// 4. Display results
// 5. Save state if needed
}Key Commands:
- Create: Generate Ed25519 keypair, optionally encrypt, save to config
- List: Display all saved wallets with status
- Show: Display wallet details and live balance
- Fund: Request testnet funds via Friendbot
- Sign: Sign messages with local or hardware keys
- Multisig: Multi-signature account management
- Search: Find templates by keyword and tags
- List: Show all available templates
- Show: Display template details
- Publish: Add template to local registry
- Remove: Delete template from registry
- Init: Initialize with example templates
- Show: Display current network and available networks
- Switch: Change active network
- Add: Register custom network
- Test: Verify network connectivity
Purpose: Reusable business logic and external integrations
Data Structure:
pub struct Config {
pub version: String,
pub network: String,
pub wallets: Vec<WalletEntry>,
pub networks: HashMap<String, NetworkConfig>,
pub telemetry_enabled: Option<bool>,
}
pub struct WalletEntry {
pub name: String,
pub public_key: String,
pub secret_key: Option<String>, // Encrypted or plaintext
pub network: String,
pub created_at: String,
pub funded: bool,
}Key Functions:
load()- Load config from~/.starforge/config.tomlsave()- Persist config to diskvalidate_*()- Input validation functionsmigrate_config()- Version migration system
Data Structure:
pub struct TemplateRegistry {
pub version: String,
pub templates: Vec<TemplateEntry>,
}
pub struct TemplateEntry {
pub name: String,
pub version: String,
pub description: String,
pub author: String,
pub tags: Vec<String>,
pub source: TemplateSource,
pub downloads: u64,
pub verified: bool,
}
pub enum TemplateSource {
Git { url: String, branch: Option<String> },
Local { path: String },
Builtin { id: String },
}Key Functions:
search_templates()- Search with filteringfetch_template()- Download from sourcevalidate_template_structure()- Verify required filespublish_template()- Add to registry
Encryption Flow:
User Password
↓
Argon2 KDF (key derivation)
↓
AES-256-GCM Key
↓
Encrypt Secret Key
↓
Store: "salt:nonce:ciphertext"
Key Functions:
prompt_password()- Secure password inputencrypt_secret()- AES-256-GCM encryptiondecrypt_secret()- Decrypt with password
Endpoints:
GET /accounts/{id}- Fetch account detailsGET /accounts/{id}/transactions- Transaction historyPOST /transactions- Submit transactionGET https://friendbot.stellar.org- Fund testnet account
Key Functions:
fetch_account()- Get account infofetch_transactions_filtered()- Get tx history with filtersfund_account()- Request testnet fundssubmit_payment_transaction()- Submit signed tx
RPC Methods:
simulateTransaction- Simulate contract callsendTransaction- Submit contract transactiongetLedgerEntries- Fetch contract datagetEvents- Stream contract events
Key Functions:
simulate_transaction()- Test contract callsubmit_transaction()- Execute contract callinspect_contract()- Get contract details
Architecture:
Plugin Interface (Trait)
↓
Plugin Implementation (.so/.dylib/.dll)
↓
Plugin Loader (libloading)
↓
Plugin Registry (JSON)
↓
Command Execution
Key Components:
interface.rs- Plugin trait definitionloader.rs- Dynamic library loadingregistry.rs- Plugin metadata storage
User Command: starforge wallet create alice --encrypt
↓
Parse Arguments (clap)
↓
Validate Wallet Name
↓
Generate Ed25519 Keypair (rand + ed25519-dalek)
↓
Prompt for Password
↓
Derive Key (Argon2) → Encrypt Secret (AES-GCM)
↓
Load Config (config.rs)
↓
Add WalletEntry to Config
↓
Save Config (TOML)
↓
Display Success
User Command: starforge new contract my-dex --template uniswap-v2 --from marketplace
↓
Parse Arguments
↓
Load Template Registry (templates.rs)
↓
Search for Template "uniswap-v2"
↓
Fetch Template (Git clone or local copy)
↓
Validate Structure (Cargo.toml, src/lib.rs)
↓
Copy to Destination
↓
Replace Placeholders:
- {{PROJECT_NAME}} → my-dex
- {{PROJECT_NAME_SNAKE}} → my_dex
- {{PROJECT_NAME_PASCAL}} → MyDex
↓
Update Download Count
↓
Display Success + Next Steps
User Command: starforge deploy --wasm contract.wasm --wallet deployer
↓
Validate WASM File
↓
Load Configuration
↓
Find Wallet "deployer"
↓
Fetch Account from Horizon
↓
Check XLM Balance
↓
Calculate WASM Hash
↓
Generate stellar CLI Command
↓
Display Command for User to Execute
User Command: starforge tx send --from alice --to bob --amount 100
↓
Validate Inputs
↓
Load Wallet "alice"
↓
Fetch Source Account (Horizon)
↓
Check Balance
↓
Build Transaction XDR
↓
Decrypt Secret Key (if encrypted)
↓
Sign Transaction (ed25519)
↓
Submit to Horizon
↓
Display Transaction Hash
| File | Purpose | Key Functions |
|---|---|---|
wallet.rs |
Wallet lifecycle management | create(), list(), show(), fund(), sign() |
template.rs |
Template marketplace | search(), publish(), list(), show() |
new.rs |
Project scaffolding | scaffold_contract(), scaffold_dapp() |
deploy.rs |
Contract deployment | handle(), validate_wasm() |
contract.rs |
Contract operations | inspect(), invoke() |
network.rs |
Network management | show(), switch(), add(), test() |
tx.rs |
Transaction handling | send(), history() |
monitor.rs |
Real-time monitoring | monitor_contract(), monitor_wallet() |
shell.rs |
Interactive REPL | handle() with REPL runner |
test.rs |
Contract testing | run_contract_tests() |
gas.rs |
Gas analysis | analyze(), optimize() |
plugin.rs |
Plugin management | install(), list(), load() |
| File | Purpose | Key Functions |
|---|---|---|
config.rs |
Config management | load(), save(), validate_*() |
templates.rs |
Template system | search_templates(), fetch_template() |
crypto.rs |
Encryption | encrypt_secret(), decrypt_secret() |
horizon.rs |
Horizon API | fetch_account(), submit_transaction() |
soroban.rs |
Soroban RPC | simulate_transaction(), inspect_contract() |
print.rs |
Terminal output | success(), error(), kv(), separator() |
hardware_wallet.rs |
HW wallet support | connect(), sign(), get_address() |
multisig.rs |
Multi-sig support | create_account(), sign_transaction() |
optimizer.rs |
WASM optimization | analyze_wasm(), optimize_wasm() |
profiler.rs |
Performance profiling | Timer, Profiler |
telemetry.rs |
Usage tracking | track_event(), set_telemetry_enabled() |
Each command is a separate module with a handle() function:
pub fn handle(cmd: CommandEnum) -> Result<()> {
match cmd {
CommandEnum::Action1 { args } => action1(args),
CommandEnum::Action2 { args } => action2(args),
}
}Benefits:
- Clear separation of concerns
- Easy to add new commands
- Testable in isolation
Configuration and data access abstracted through utility modules:
// config.rs acts as repository
pub fn load() -> Result<Config> { /* ... */ }
pub fn save(config: &Config) -> Result<()> { /* ... */ }Benefits:
- Centralized data access
- Easy to change storage backend
- Consistent error handling
Template sources use enum with different strategies:
pub enum TemplateSource {
Git { url: String, branch: Option<String> },
Local { path: String },
Builtin { id: String },
}
pub fn fetch_template(source: &TemplateSource) -> Result<()> {
match source {
TemplateSource::Git { url, branch } => fetch_git(url, branch),
TemplateSource::Local { path } => fetch_local(path),
TemplateSource::Builtin { id } => fetch_builtin(id),
}
}Used in configuration and complex structures:
let stream = SorobanEventStream::new(rpc_url, contract_id)
.with_poll_interval(5)
.with_filter(event_types);Print utilities provide simple interface to complex terminal operations:
p::header("Title");
p::kv("Key", "Value");
p::success("Done!");- Create new file in
src/commands/ - Define command enum with clap attributes
- Implement
handle()function - Add to
src/commands/mod.rs - Add to
Commandsenum insrc/main.rs
- Add variant to
TemplateSourceenum - Implement fetch logic in
fetch_template() - Update validation if needed
- Implement
Plugintrait - Compile as dynamic library
- Register with
starforge plugin install
starforge network add mynet \
--horizon-url https://horizon.example.com \
--soroban-rpc-url https://soroban.example.com- Add field to
Configstruct - Update
Defaultimplementation - Add migration in
migrate_config() - Update version number
Plaintext Mode:
Secret Key → Config File (NOT RECOMMENDED)
Encrypted Mode:
Secret Key → Argon2 KDF → AES-256-GCM → Config File
User Request → HID API → Hardware Device → Signature
All user inputs validated before processing:
- Public keys: 56 chars, starts with 'G', base32
- Contract IDs: 56 chars, starts with 'C', base32
- Amounts: Positive numbers
- Wallet names: Alphanumeric + dash/underscore
- HTTPS for all API calls
- Mainnet warnings for destructive operations
- Confirmation prompts for high-risk actions
Config loaded once per command execution, cached in memory.
Registry loaded on-demand, not at startup.
Shallow clones (--depth 1) for faster template fetching.
Independent operations can be parallelized (future enhancement).
All fallible operations return Result<T, anyhow::Error>:
pub fn operation() -> Result<()> {
validate_input()?;
perform_action()?;
Ok(())
}Errors enriched with context:
fs::read_to_string(&path)
.with_context(|| format!("Failed to read {}", path.display()))?Errors displayed with helpful suggestions:
✗ Error: Wallet 'alice' not found
Try: starforge wallet list
In-module tests for individual functions:
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_validate_public_key() {
assert!(validate_public_key("GABC...").is_ok());
}
}In tests/ directory for end-to-end workflows.
For validation functions (future enhancement).
Convert blocking I/O to async for better performance:
pub async fn fetch_account(key: &str) -> Result<Account> {
// Async HTTP request
}Replace TOML config with SQLite for better querying:
Config File → SQLite Database
Central server for global template sharing:
Local Registry → Remote API → Global Registry
Run StarForge in browser via WASM.
Expose StarForge functionality via GraphQL.
StarForge provides a comprehensive contract upgrade workflow that supports both single-signer and multi-signature governance models. The upgrade system persists proposal state locally in ~/.starforge/upgrades/ to enable team collaboration and approval workflows.
~/.starforge/
└── upgrades/
├── proposals.json # Active and historical proposals
└── history.json # Executed upgrade records
pub struct UpgradeProposal {
pub id: String, // Unique ID: "prop-{wasm_hash_prefix}"
pub contract_id: String, // Contract to upgrade
pub new_wasm_hash: String, // SHA-256 hash of new WASM
pub description: String, // Human-readable reason
pub proposer: String, // Public key of proposer
pub approvals: Vec<String>, // Public keys of approvers
pub threshold: u8, // Required approvals
pub status: ProposalStatus, // Pending/Approved/Executed/Rejected/Expired
pub network: String, // testnet/mainnet
pub created_at: String, // RFC3339 timestamp
pub executed_at: Option<String>, // RFC3339 timestamp when executed
}pub struct UpgradeRecord {
pub contract_id: String,
pub from_hash: String,
pub to_hash: String,
pub proposal_id: String,
pub executed_by: String,
pub network: String,
pub timestamp: String,
}┌─────────────────────────────────────────────────────────────┐
│ 1. Prepare Upgrade │
│ starforge upgrade prepare --contract-id C... --wasm new.wasm │
│ • Validates WASM file │
│ • Computes SHA-256 hash │
│ • Verifies contract exists on-chain │
└─────────────────────┬───────────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ 2. Create Proposal │
│ starforge upgrade propose --contract-id C... --wasm new.wasm │
│ --description "Fix bug X" │
│ • Creates proposal with threshold=1 │
│ • Auto-approves (proposer approval) │
│ • Saves to proposals.json │
│ • Status: Approved │
└─────────────────────┬───────────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ 3. Execute Upgrade │
│ starforge upgrade execute --proposal-id prop-abc123 │
│ • Verifies status is Approved │
│ • Generates stellar CLI commands │
│ • Records in history.json │
│ • Updates proposal status to Executed │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ Team Member 1: Create Proposal │
│ starforge upgrade propose --contract-id C... │
│ --wasm new.wasm │
│ --description "Add feature Y" │
│ --threshold 3 │
│ --wallet alice │
│ • Creates proposal requiring 3 approvals │
│ • Alice auto-approves (1/3) │
│ • Saves to proposals.json │
│ • Status: Pending │
└─────────────────────┬───────────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ Team Member 2: Review and Approve │
│ starforge upgrade list │
│ starforge upgrade status --proposal-id prop-abc123 │
│ • Reviews proposal details │
│ • Verifies WASM hash matches expectations │
│ │
│ starforge upgrade approve --proposal-id prop-abc123 │
│ --wallet bob │
│ • Bob approves (2/3) │
│ • Updates proposals.json │
│ • Status: Still Pending │
└─────────────────────┬───────────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ Team Member 3: Final Approval │
│ starforge upgrade approve --proposal-id prop-abc123 │
│ --wallet charlie │
│ • Charlie approves (3/3) │
│ • Threshold reached │
│ • Status: Approved │
└─────────────────────┬───────────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ Any Team Member: Execute │
│ starforge upgrade execute --proposal-id prop-abc123 │
│ --wallet alice │
│ • Verifies threshold met │
│ • Generates on-chain commands │
│ • Records execution in history.json │
│ • Status: Executed │
└─────────────────────────────────────────────────────────────┘
The upgrade workflow integrates seamlessly with Stellar multi-signature accounts:
pub struct MultiSigAccount {
pub name: String,
pub account_id: String,
pub signers: Vec<Signer>, // Multiple signers with weights
pub thresholds: Thresholds, // Low/Medium/High thresholds
pub created_at: String,
}
pub struct Signer {
pub public_key: String,
pub weight: u8, // Voting weight
pub name: Option<String>,
}
pub struct Thresholds {
pub low: u8, // For low-security operations
pub medium: u8, // For medium-security operations
pub high: u8, // For high-security operations (upgrades)
}┌─────────────────────────────────────────────────────────────┐
│ Scenario: Upgrade contract controlled by multi-sig account │
│ │
│ Multi-Sig Account: "dao-treasury" │
│ • Signer 1 (Alice): weight=10 │
│ • Signer 2 (Bob): weight=10 │
│ • Signer 3 (Carol): weight=10 │
│ • High threshold: 20 (requires 2 of 3) │
└─────────────────────────────────────────────────────────────┘
Step 1: Create Upgrade Proposal (Off-Chain Governance)
starforge upgrade propose --contract-id C... --threshold 2
• Tracks approvals in StarForge
• Ensures team consensus before on-chain action
Step 2: Collect Approvals (Off-Chain)
starforge upgrade approve --proposal-id prop-abc123 --wallet alice
starforge upgrade approve --proposal-id prop-abc123 --wallet bob
• Proposal status: Approved (2/2 threshold met)
Step 3: Generate Multi-Sig Transaction (On-Chain Preparation)
starforge upgrade execute --proposal-id prop-abc123
• Generates transaction XDR for upgrade
• Transaction requires multi-sig account signatures
Step 4: Collect On-Chain Signatures
stellar contract invoke --id C... --source dao-treasury \
--network testnet -- upgrade --new-wasm-hash <hash>
• Stellar network validates multi-sig thresholds
• Requires signatures from signers with combined weight ≥ 20
• Alice (weight=10) + Bob (weight=10) = 20 ✓
Step 5: Submit to Network
• Transaction submitted with sufficient signatures
• Contract upgraded on-chain
• StarForge records in history.json
- Use StarForge upgrade proposals for team coordination
- Contract controlled by single account
- Approval threshold enforced by StarForge
- Suitable for: Small teams, testnet deployments
- Use Stellar multi-sig accounts
- No StarForge proposal system
- Approval threshold enforced by blockchain
- Suitable for: Decentralized protocols, mainnet
- StarForge proposals for off-chain coordination
- Multi-sig accounts for on-chain enforcement
- Double-layer security and consensus
- Suitable for: DAOs, enterprise deployments
┌─────────┐
│ Created │
└────┬────┘
│
▼
┌──────────────────────────────────────┐
│ Pending │
│ (approvals < threshold) │
└────┬─────────────────────────┬────────┘
│ │
│ Approvals++ │ Timeout/Reject
▼ ▼
┌─────────┐ ┌──────────┐
│Approved │ │ Rejected │
│ │ │ Expired │
└────┬────┘ └──────────┘
│
│ Execute
▼
┌─────────┐
│Executed │
└─────────┘
| Command | Purpose | Persistence |
|---|---|---|
upgrade prepare |
Validate WASM and preview upgrade | None |
upgrade propose |
Create proposal with threshold | Writes to proposals.json |
upgrade list |
Show all proposals | Reads from proposals.json |
upgrade status |
Show proposal status (alias for list) | Reads from proposals.json |
upgrade approve |
Add approval to proposal | Updates proposals.json |
upgrade execute |
Generate on-chain commands | Updates proposals.json, writes to history.json |
upgrade history |
Show past upgrades | Reads from history.json |
upgrade rollback |
Revert to previous version | Reads from history.json |
[
{
"id": "prop-a1b2c3d4e5f6",
"contract_id": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
"new_wasm_hash": "a1b2c3d4e5f6...",
"description": "Fix critical bug in transfer function",
"proposer": "GDALICE...",
"approvals": ["GDALICE...", "GDBOB..."],
"threshold": 2,
"status": "approved",
"network": "testnet",
"created_at": "2025-01-15T10:30:00Z",
"executed_at": null
}
][
{
"contract_id": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
"from_hash": "old_hash_123...",
"to_hash": "new_hash_456...",
"proposal_id": "prop-a1b2c3d4e5f6",
"executed_by": "GDALICE...",
"network": "testnet",
"timestamp": "2025-01-15T11:00:00Z"
}
]- WASM Hash Verification: All approvers should independently verify the WASM hash matches the expected code
- Network Isolation: Proposals are network-specific (testnet/mainnet) to prevent cross-network confusion
- Threshold Enforcement: Off-chain thresholds prevent premature execution
- Audit Trail: Complete history of proposals and executions for compliance
- Mainnet Warnings: Extra confirmation prompts for mainnet upgrades
- Always use
preparefirst: Validate WASM before creating proposals - Set appropriate thresholds: Match your team's governance requirements
- Document descriptions: Clear upgrade rationale helps reviewers
- Test on testnet: Validate upgrade flow before mainnet
- Backup history: Regularly backup
~/.starforge/upgrades/directory - Coordinate with team: Share proposal IDs through secure channels
- Verify WASM independently: Don't trust, verify the hash
If an upgrade causes issues, use the rollback feature:
# View upgrade history
starforge upgrade history --contract-id C... --network testnet
# Rollback to previous version
starforge upgrade rollback --contract-id C... \
--to-hash <previous_hash> \
--network testnetThe rollback creates a new upgrade proposal pointing to the previous WASM hash, following the same approval workflow.
StarForge's architecture is designed for:
- Maintainability: Clear module boundaries
- Extensibility: Plugin system and extension points
- Reliability: Type safety and error handling
- Performance: Efficient operations and caching
- Security: Encryption and validation throughout
The modular design allows for easy addition of new features while maintaining code quality and user experience.