No description
  • Shell 57.7%
  • Rust 38.3%
  • Makefile 4%
Find a file
mik-tf 4846683922
Some checks failed
Build Linux / build-linux (linux-amd64, false, x86_64-unknown-linux-musl) (push) Failing after 21s
Build Linux / build-linux (linux-arm64, true, aarch64-unknown-linux-gnu) (push) Failing after 20s
Build and Test / build-and-test (push) Successful in 5m0s
Merge pull request 'standardize: naming and dependency conventions' (#1) from development_hero_zero_standardize into main
2026-02-12 01:05:23 +00:00
.forgejo/workflows Initial commit: hero_launcher backend with Stripe integration 2026-02-09 09:55:11 +01:00
docs Initial commit: hero_launcher backend with Stripe integration 2026-02-09 09:55:11 +01:00
scripts fix: Makefile compliance - move port-killing to scripts/stop-ports.sh 2026-02-11 17:06:39 -05:00
sdk/rust standardize: rename hero_launcher-sdk → hero_launcher_sdk 2026-02-11 18:52:12 -05:00
src Initial commit: hero_launcher backend with Stripe integration 2026-02-09 09:55:11 +01:00
.gitignore fix gitignore to exclude nested target dirs, track SDK lock file 2026-02-10 12:16:07 +01:00
buildenv.sh standardize: clear PORTS (hero_launcher is not a network service) 2026-02-11 15:42:14 -05:00
Cargo.lock Initial commit: hero_launcher backend with Stripe integration 2026-02-09 09:55:11 +01:00
Cargo.toml Fix CI: add 'full' feature so build_lib --features works 2026-02-09 10:38:51 +01:00
Makefile fix: Makefile compliance - move port-killing to scripts/stop-ports.sh 2026-02-11 17:06:39 -05:00
README.md Initial commit: hero_launcher backend with Stripe integration 2026-02-09 09:55:11 +01:00

Hero Launcher

JSON-RPC server that provisions and manages hero backends in Our Cyberspace. It receives requests from the www_herozero frontend, launches containerized hero_zero instances, and handles admin operations like DNS name registration.

System Flow

┌──────────────┐     JSON-RPC      ┌────────────────┐    podman/docker    ┌──────────────┐
│  www_herozero │ ──────────────► │  hero_launcher  │ ─────────────────► │  hero_zero   │
│  (Dioxus UI)  │  hero.create    │  (Axum server)  │   container run    │  (container) │
└──────────────┘                  └────────┬───────┘                    └──────┬───────┘
                                           │                                   │
                                  ┌────────▼───────┐                  ┌────────▼───────┐
                                  │     Redis      │                  │  hero_ledger   │
                                  │  (hero state)  │                  │  (NEAR chain)  │
                                  └────────────────┘                  └────────────────┘
  1. User fills out the join form on www_herozero
  2. Frontend calls hero.create on hero_launcher
  3. Launcher generates a mycelium keypair (x25519 + BLAKE3 address derivation)
  4. Launcher starts a hero_zero container with env vars (HERO_ID, HERO_PASSWORD, etc.)
  5. hero_zero auto-initializes: creates NEAR account, encrypts key, registers on ledger
  6. Launcher registers DNS name on the ledger (admin-only, triggered after payment)

Quick Start

# Build
cargo build --release

# Run (requires podman or docker, optionally Redis)
./target/release/hero_launcher

# With options
./target/release/hero_launcher \
  --listen 0.0.0.0:4000 \
  --runtime podman \
  --image hero_zero:latest \
  --redis-url redis://127.0.0.1:6379

CLI Options

Flag Default Description
--listen 0.0.0.0:4000 Server listen address
--redis-url redis://127.0.0.1:6379 Redis URL for state persistence
--runtime podman Container runtime (podman or docker)
--image hero_zero:latest Hero Zero container image
--mycelium-peers tcp://188.40.132.242:9651 Mycelium peer endpoints (comma-separated)
--ledger-network local NEAR ledger network (local, dev, test, main)
--ledger-activation-url http://localhost:8080 Faucet/relayer endpoint
--log-level info Log level

JSON-RPC API

Endpoint: POST /rpc

All methods use JSON-RPC 2.0 over HTTP.

hero.create

Create a new hero. Generates a mycelium identity, persists keys, and launches a hero_zero container.

{
  "jsonrpc": "2.0",
  "method": "hero.create",
  "params": {
    "password": "user-chosen-password",
    "name": "heroname",
    "tier": 1
  },
  "id": 1
}

Params:

Field Type Required Description
password string yes Password for encrypting the hero's private key
name string no Requested hero name (DNS registration done separately)
tier number no Tier: 0=Explorer (free), 1=Pioneer ($10/mo), 2=Founder ($50/mo)

Response:

{
  "hero_id": "uuid",
  "mycelium_address": "4xx:xxxx:...",
  "mycelium_pubkey": "hex64",
  "status": "launching"
}

The container launches in the background. Poll hero.status to track progress through: launchinginitializingrunning.

hero.status

Get current status and details for a hero.

{
  "jsonrpc": "2.0",
  "method": "hero.status",
  "params": { "hero_id": "uuid" },
  "id": 1
}

Response: Full HeroRecord object with fields: hero_id, container_id, mycelium_addr, mycelium_pubkey, account_id, name, tier, status, created_at, error.

hero.list

List all heroes managed by this launcher.

{
  "jsonrpc": "2.0",
  "method": "hero.list",
  "params": {},
  "id": 1
}

Response: Array of HeroRecord objects.

hero.stop

Stop a running hero container.

{
  "jsonrpc": "2.0",
  "method": "hero.stop",
  "params": { "hero_id": "uuid" },
  "id": 1
}

hero.logs

Get recent logs from a hero container.

{
  "jsonrpc": "2.0",
  "method": "hero.logs",
  "params": { "hero_id": "uuid", "tail": 100 },
  "id": 1
}

hero.register_name

Admin-only. Register a DNS name on the ledger identity contract. This is separated from hero.create because it requires payment verification — only the launcher (not the hero container) has admin access to the DNS contract.

{
  "jsonrpc": "2.0",
  "method": "hero.register_name",
  "params": {
    "hero_id": "uuid",
    "name": "heroname"
  },
  "id": 1
}

Response:

{
  "hero_id": "uuid",
  "name": "heroname",
  "status": "registered"
}

Architecture

src/
├── main.rs              # CLI entry point (clap)
├── config.rs            # LauncherConfig + path helpers
├── server.rs            # Axum JSON-RPC server + dispatch
├── store.rs             # Redis-backed hero state (HeroRecord, HeroStatus)
├── rpc/
│   ├── mod.rs
│   └── hero.rs          # RPC method handlers
├── mycelium/
│   ├── mod.rs
│   └── keygen.rs        # x25519 keypair + BLAKE3 address derivation
└── container/
    ├── mod.rs
    └── manager.rs       # podman/docker lifecycle (launch, stop, logs)

Mycelium Key Generation

Each hero gets a unique mycelium identity for cryptographically-verified E2E communication:

  1. Generate x25519 keypair (Diffie-Hellman)
  2. BLAKE3 hash the public key → 16 bytes via XOF
  3. Set first byte to 0x04 or 0x05 (parity) → IPv6 address in 400::/7

The secret key is written to disk and mounted into the container at /hero/mycelium/priv_key.bin. The container's mycelium daemon uses this key, giving the hero its own network identity.

Container Launch

Each hero runs in a container with:

  • --network host — shares host network (mycelium needs TUN)
  • --cap-add NET_ADMIN + --device /dev/net/tun — for mycelium
  • Volume mounts: mycelium key (read-only), hero data dir
  • Environment variables: HERO_ID, HERO_PASSWORD, HERO_MYCELIUM_ADDR, HERO_LEDGER_NETWORK, HERO_LEDGER_ACTIVATION_URL

The container runs hero_zero which auto-initializes on first boot (see hero_zero docs).

State Storage

Hero records are stored in Redis:

  • hero:{id} — JSON-serialized HeroRecord
  • heroes — Set of all hero IDs

If Redis is unavailable, the server starts with a noop store (state won't persist across restarts).

Host Data Layout

~/hero_launcher/
└── heroes/
    └── {hero_id}/
        ├── mycelium/
        │   └── priv_key.bin    # 32-byte x25519 secret key
        └── var/                # Mounted as /hero/var in container

Dependencies

  • Runtime: podman or docker
  • Optional: Redis (for persistent state)
  • Network: hero_ledger (NEAR blockchain, for account activation + DNS)

License

Apache-2.0