From 03fea90cc838b44d470f1c26608c2fef0c3e805b Mon Sep 17 00:00:00 2001 From: juvdiaz Date: Mon, 29 Jun 2026 19:18:45 -0600 Subject: [PATCH] Add blockchain wallet signing lab --- README.md | 5 ++ README.md.tmpl | 5 ++ docs/jeannie.1.md | 4 ++ jeannie | 9 ++++ labs/blockchain/WALLET_LAB.md | 37 +++++++++++++++ scripts/blockchain-wallet | 86 +++++++++++++++++++++++++++++++++++ 6 files changed, 146 insertions(+) create mode 100644 labs/blockchain/WALLET_LAB.md create mode 100755 scripts/blockchain-wallet diff --git a/README.md b/README.md index fb6f851..f4613ba 100644 --- a/README.md +++ b/README.md @@ -285,6 +285,7 @@ Run a read-only health snapshot from the Debian server with: ./jeannie artifact-cache status ./jeannie blockchain-devnet status ./jeannie blockchain-test +./jeannie blockchain-wallet instructions ./jeannie golden-ledger check ./jeannie route-inventory ./jeannie workers list @@ -379,6 +380,10 @@ learning only; never use real seed phrases or mainnet keys. with a simple `Counter` contract and ownership tests so there is a known-good baseline before practicing vulnerable contracts. +`blockchain-wallet` provides disposable dev-wallet generation, address +derivation, and message-signing practice. It is documented in +`labs/blockchain/WALLET_LAB.md`; never use real seed phrases or funded keys. + `golden-ledger` shows or validates `infra/pimox/golden-image-ledger.yml`, the reviewable record of template VMID, storage, OS release, Kubernetes pins, runtime versions, and build metadata for Pimox worker golden images. diff --git a/README.md.tmpl b/README.md.tmpl index 926b31d..e37618f 100644 --- a/README.md.tmpl +++ b/README.md.tmpl @@ -285,6 +285,7 @@ Run a read-only health snapshot from the Debian server with: ./{{ main_script }} artifact-cache status ./{{ main_script }} blockchain-devnet status ./{{ main_script }} blockchain-test +./{{ main_script }} blockchain-wallet instructions ./{{ main_script }} golden-ledger check ./{{ main_script }} route-inventory ./{{ main_script }} workers list @@ -379,6 +380,10 @@ learning only; never use real seed phrases or mainnet keys. with a simple `Counter` contract and ownership tests so there is a known-good baseline before practicing vulnerable contracts. +`blockchain-wallet` provides disposable dev-wallet generation, address +derivation, and message-signing practice. It is documented in +`labs/blockchain/WALLET_LAB.md`; never use real seed phrases or funded keys. + `golden-ledger` shows or validates `infra/pimox/golden-image-ledger.yml`, the reviewable record of template VMID, storage, OS release, Kubernetes pins, runtime versions, and build metadata for Pimox worker golden images. diff --git a/docs/jeannie.1.md b/docs/jeannie.1.md index 3f97f12..4807bc4 100644 --- a/docs/jeannie.1.md +++ b/docs/jeannie.1.md @@ -131,6 +131,10 @@ phrases or mainnet keys. : Run the Foundry smart contract tests in `labs/blockchain`. Extra arguments are passed through to `forge test`. +`blockchain-wallet {instructions|new|address|sign-message MESSAGE}` +: Practice dev wallet generation, address derivation, and message signing with +Foundry Cast. Use disposable Anvil/dev keys only. + `golden-ledger {show|check}` : Show or validate the Pimox golden image version ledger. diff --git a/jeannie b/jeannie index 22007d5..44bce14 100755 --- a/jeannie +++ b/jeannie @@ -6016,6 +6016,10 @@ blockchain_test() { "${REPO_ROOT}/scripts/blockchain-test" "${@:2}" } +blockchain_wallet() { + "${REPO_ROOT}/scripts/blockchain-wallet" "${@:2}" +} + golden_ledger() { "${REPO_ROOT}/scripts/golden-ledger" "${@:2}" } @@ -6085,6 +6089,8 @@ Build And Bootstrap blockchain-devnet {status|up|down|logs|rpc} Manage the local Ethereum Anvil devnet. blockchain-test [forge args...] Run Foundry tests for labs/blockchain. + blockchain-wallet {instructions|new|address|sign-message} + Practice dev wallet and signing workflows. golden-ledger {show|check} Show or validate Pimox golden image versions. Cluster Lifecycle @@ -6226,6 +6232,9 @@ case "${1:-}" in blockchain-test) blockchain_test "$@" ;; + blockchain-wallet) + blockchain_wallet "$@" + ;; golden-ledger) golden_ledger "$@" ;; diff --git a/labs/blockchain/WALLET_LAB.md b/labs/blockchain/WALLET_LAB.md new file mode 100644 index 0000000..c6a880f --- /dev/null +++ b/labs/blockchain/WALLET_LAB.md @@ -0,0 +1,37 @@ +# Wallet And Signing Lab + +This lab is for disposable development wallets only. + +Do not use: + +- real seed phrases +- hardware wallet recovery words +- funded private keys +- exchange account keys + +## Commands + +```bash +./jeannie blockchain-wallet instructions +./jeannie blockchain-wallet new +export PRIVATE_KEY=0x... +./jeannie blockchain-wallet address +./jeannie blockchain-wallet sign-message "homelab devnet login" +``` + +## What To Learn + +- A private key controls an address. +- A signature proves control of a private key without revealing it. +- A transaction signature authorizes state change on a specific chain. +- Chain IDs matter because they prevent replay across networks. +- Seed phrases and private keys are secrets, not configuration. + +## Safe Practice Flow + +1. Start the devnet with `./jeannie blockchain-devnet up`. +2. Use one of Anvil's printed dev private keys or generate a disposable key. +3. Derive the address. +4. Sign a harmless message. +5. Verify the address and signature with Foundry/Cast experiments. +6. Throw away the key when done. diff --git a/scripts/blockchain-wallet b/scripts/blockchain-wallet new file mode 100755 index 0000000..f3ee4e5 --- /dev/null +++ b/scripts/blockchain-wallet @@ -0,0 +1,86 @@ +#!/usr/bin/env bash +set -euo pipefail + +FOUNDRY_IMAGE="${FOUNDRY_IMAGE:-ghcr.io/foundry-rs/foundry:latest}" + +usage() { + cat <<'EOF' +Usage: ./jeannie blockchain-wallet {instructions|new|address|sign-message MESSAGE} + +instructions Print wallet lab guidance. +new Generate a new development wallet. +address Print the address for PRIVATE_KEY. +sign-message MESSAGE Sign a dev message with PRIVATE_KEY. + +Set PRIVATE_KEY only with an Anvil/dev private key. Never use a real wallet key. +EOF +} + +run_cast() { + if command -v cast >/dev/null 2>&1; then + cast "$@" + return + fi + + if ! command -v docker >/dev/null 2>&1; then + echo "cast or docker is required for blockchain-wallet." >&2 + exit 1 + fi + + docker run --rm \ + -e "PRIVATE_KEY=${PRIVATE_KEY:-}" \ + "$FOUNDRY_IMAGE" \ + cast "$@" +} + +require_private_key() { + if [ -z "${PRIVATE_KEY:-}" ]; then + echo "Set PRIVATE_KEY to an Anvil/dev private key first." >&2 + exit 1 + fi +} + +case "${1:-instructions}" in + instructions) + cat <<'EOF' +Wallet lab rules: + - Use only Anvil or disposable development keys. + - Never paste a real seed phrase or funded private key into this repo or shell. + - Prefer environment variables for short-lived dev keys. + - Treat signatures as authorization; verify what you are signing. + +Examples: + ./jeannie blockchain-wallet new + export PRIVATE_KEY=0x... + ./jeannie blockchain-wallet address + ./jeannie blockchain-wallet sign-message "homelab devnet login" + +Pair this with: + ./jeannie blockchain-devnet up + ./jeannie blockchain-devnet rpc +EOF + ;; + new) + run_cast wallet new + ;; + address) + require_private_key + run_cast wallet address "$PRIVATE_KEY" + ;; + sign-message) + require_private_key + shift + if [ "$#" -eq 0 ]; then + echo "sign-message requires a message." >&2 + exit 1 + fi + run_cast wallet sign --private-key "$PRIVATE_KEY" "$*" + ;; + -h|--help|help) + usage + ;; + *) + usage >&2 + exit 1 + ;; +esac