* clear

* feat: Add everything

* fix: Commenht
This commit is contained in:
Prad Nukala
2025-10-03 14:45:52 -04:00
committed by GitHub
parent 43b4a11c06
commit 13e6c3e84d
1935 changed files with 655061 additions and 40058 deletions
+163
View File
@@ -0,0 +1,163 @@
#!/bin/sh
# cli-docgen.sh
# A shell script to generate CLI documentation by walking the installed snrd binary.
# This script assumes snrd is already installed and available in PATH.
set -e # Exit immediately if a command exits with a non-zero status.
# --- Default Values ---
OUT_DIR="./docs/cli"
# --- Usage Function ---
usage() {
echo "Usage: $0 [--out <dir>] [--help]"
echo
echo "Options:"
echo " --out <dir> Specify the output directory."
echo " (Default: ./docs/cli)"
echo " --help Display this help message."
exit 1
}
# --- Argument Parsing ---
while [ "$#" -gt 0 ]; do
case "$1" in
--out)
if [ -n "$2" ]; then
OUT_DIR="$2"
shift 2
else
echo "Error: --out requires a directory path." >&2
usage
fi
;;
--help)
usage
;;
*)
echo "Error: Unknown option '$1'" >&2
usage
;;
esac
done
# --- Main Logic ---
# Check if snrd binary is installed
if ! command -v snrd >/dev/null 2>&1; then
echo "Error: snrd binary not found in PATH." >&2
echo "Please run 'make install' first to install the snrd binary." >&2
exit 1
fi
# Create output directory
echo "Creating output directory: $OUT_DIR"
mkdir -p "$OUT_DIR"
# Clean existing files
echo "Cleaning existing documentation..."
rm -f "$OUT_DIR"/*.md
# Function to sanitize filename
sanitize_filename() {
echo "$1" | tr ' ' '_' | tr '/' '-' | tr -d '[](){}' | sed 's/^-//;s/-$//'
}
# Generate main command documentation
echo "Generating documentation for snrd..."
# Main snrd help
snrd --help >"$OUT_DIR/snrd.md" 2>&1 || true
echo "Generated: $OUT_DIR/snrd.md"
# Get list of main commands
echo "Walking command tree..."
# Primary commands we want to document
MAIN_COMMANDS="auth genesis help init keys migrate node prune query rollback status tendermint tx version"
# Generate documentation for each main command
for cmd in $MAIN_COMMANDS; do
echo "Processing: snrd $cmd"
# Generate main command doc
filename=$(sanitize_filename "$cmd")
snrd "$cmd" --help >"$OUT_DIR/snrd_${filename}.md" 2>&1 || true
echo " Generated: $OUT_DIR/snrd_${filename}.md"
# Special handling for commonly used sub-commands
case "$cmd" in
"query")
# Document query sub-modules
QUERY_MODULES="account accounts auth bank consensus delegation did distribution dwn feegrant gov slashing staking svc tendermint tx"
for module in $QUERY_MODULES; do
echo " Processing: snrd query $module"
filename=$(sanitize_filename "query_${module}")
snrd query "$module" --help >"$OUT_DIR/snrd_${filename}.md" 2>&1 || true
done
;;
"tx")
# Document tx sub-modules
TX_MODULES="bank consensus crisis did distribution dwn feegrant gov slashing staking svc"
for module in $TX_MODULES; do
echo " Processing: snrd tx $module"
filename=$(sanitize_filename "tx_${module}")
snrd tx "$module" --help >"$OUT_DIR/snrd_${filename}.md" 2>&1 || true
done
;;
"keys")
# Document keys sub-commands
KEYS_COMMANDS="add delete export import list migrate parse show"
for subcmd in $KEYS_COMMANDS; do
echo " Processing: snrd keys $subcmd"
filename=$(sanitize_filename "keys_${subcmd}")
snrd keys "$subcmd" --help >"$OUT_DIR/snrd_${filename}.md" 2>&1 || true
done
;;
"auth")
# Document auth sub-commands
AUTH_COMMANDS="register verify sign"
for subcmd in $AUTH_COMMANDS; do
echo " Processing: snrd auth $subcmd"
filename=$(sanitize_filename "auth_${subcmd}")
snrd auth "$subcmd" --help >"$OUT_DIR/snrd_${filename}.md" 2>&1 || true
done
;;
"genesis")
# Document genesis sub-commands
GENESIS_COMMANDS="add-genesis-account collect-txs export gentx init migrate validate"
for subcmd in $GENESIS_COMMANDS; do
echo " Processing: snrd genesis $subcmd"
filename=$(sanitize_filename "genesis_${subcmd}")
snrd genesis "$subcmd" --help >"$OUT_DIR/snrd_${filename}.md" 2>&1 || true
done
;;
esac
done
# Generate index file with all commands
echo "Generating index file..."
cat >"$OUT_DIR/index.md" <<EOF
# Sonr CLI Documentation
This documentation is auto-generated from the \`snrd\` binary.
## Main Commands
EOF
# Add links to all generated files
for file in "$OUT_DIR"/snrd*.md; do
if [ -f "$file" ]; then
basename=$(basename "$file" .md)
# Convert filename back to readable format
readable_name=$(echo "$basename" | sed 's/snrd_//' | tr '_' ' ' | sed 's/-/ /g')
echo "- [$readable_name](./$basename.md)" >>"$OUT_DIR/index.md"
fi
done
echo ""
echo "Documentation generation complete!"
echo "Files generated in: $OUT_DIR"
echo "Total files: $(ls -1 "$OUT_DIR"/*.md 2>/dev/null | wc -l)"
+58
View File
@@ -0,0 +1,58 @@
const converter = require('swagger2openapi');
const glob = require('glob');
const fs = require('fs').promises;
const yaml = require('yaml');
/**
* Script to find and convert Swagger 2.0 YAML files to OpenAPI 3.0 in-place.
*/
async function convertAll() {
// Define options for the swagger2openapi converter.
// Set 'patch' to true to perform some cleanup and fixing operations.
const options = { patch: true, warnOnly: true };
try {
// 1. Find all files ending with .swagger.yaml in the target directory.
const swaggerFiles = glob.sync('docs/static/openapi/*.swagger.yaml');
if (swaggerFiles.length === 0) {
console.log(
"Conversion script finished: No *.swagger.yaml files were found in 'docs/static/openapi/'."
);
return;
}
console.log(`Found ${swaggerFiles.length} Swagger file(s) to convert.`);
// 2. Create a list of conversion promises.
const conversionPromises = swaggerFiles.map(async (filePath) => {
try {
console.log(`- Converting ${filePath}...`);
// 3. Convert the file. The result object contains the OpenAPI definition.
const { openapi } = await converter.convertFile(filePath, options);
// 4. Serialize the resulting OpenAPI object back to a YAML string.
const openapiYamlString = yaml.stringify(openapi);
// 5. Overwrite the original file with the new OpenAPI 3.0 content.
await fs.writeFile(filePath, openapiYamlString, 'utf8');
console.log(` √ Successfully converted and overwritten ${filePath}`);
} catch (err) {
console.error(` × Failed to convert ${filePath}:`, err.message);
}
});
// 6. Wait for all file conversions to complete.
await Promise.all(conversionPromises);
console.log('\nConversion process complete.');
} catch (error) {
console.error('\nAn unexpected error occurred:', error);
process.exit(1); // Exit with an error code
}
}
// Run the conversion process.
convertAll();
+146
View File
@@ -0,0 +1,146 @@
#!/bin/bash
set -eux
# generate_vrf_key generates a VRF keypair and stores it securely
generate_vrf_key() {
local home_dir="$1"
if [[ -z "${home_dir}" ]]; then
echo "Error: HOME_DIR parameter is required" >&2
return 1
fi
local genesis_file="${home_dir}/config/genesis.json"
if [[ ! -f "${genesis_file}" ]]; then
echo "Error: Genesis file not found at ${genesis_file}" >&2
return 1
fi
local chain_id
chain_id=$(jq -r '.chain_id' "${genesis_file}" 2>/dev/null)
if [[ -z "${chain_id}" || "${chain_id}" == "null" ]]; then
echo "Error: Failed to extract chain-id from genesis file" >&2
return 1
fi
echo "Generating VRF keypair for network: ${chain_id}"
local entropy_seed
entropy_seed=$(echo -n "${chain_id}" | sha256sum | cut -d' ' -f1)
local seed_part1="${entropy_seed}"
local seed_part2
seed_part2=$(echo -n "${entropy_seed}" | sha256sum | cut -d' ' -f1)
local vrf_key_hex="${seed_part1}${seed_part2}"
if [[ ${#vrf_key_hex} -ne 128 ]]; then
echo "Error: Generated VRF key has incorrect size: ${#vrf_key_hex}" >&2
return 1
fi
local vrf_key_path="${home_dir}/vrf_secret.key"
mkdir -p "${home_dir}"
echo -n "${vrf_key_hex}" | xxd -r -p > "${vrf_key_path}"
chmod 0600 "${vrf_key_path}"
local file_size
file_size=$(wc -c < "${vrf_key_path}")
if [[ ${file_size} -ne 64 ]]; then
echo "Error: VRF key file has incorrect size: ${file_size} bytes" >&2
rm -f "${vrf_key_path}"
return 1
fi
echo "✓ VRF keypair generated for network: ${chain_id}"
echo "✓ VRF secret key stored securely: ${vrf_key_path}"
return 0
}
DENOM="${DENOM:=usnr}"
# Match init-testnet.sh allocation: 100000000000000000000000000snr = 100000000000000000000000000000000usnr
COINS="${COINS:=100000000000000000000000000000000$DENOM,100000000000000000000000000snr}"
CHAIN_ID="${CHAIN_ID:=sonrtest_1-1}"
CHAIN_BIN="${CHAIN_BIN:=snrd}"
CHAIN_DIR="${CHAIN_DIR:=$HOME/.sonr}"
KEYS_CONFIG="${KEYS_CONFIG:=configs/keys.json}"
FAUCET_ENABLED="${FAUCET_ENABLED:=true}"
NUM_VALIDATORS="${NUM_VALIDATORS:=1}"
NUM_RELAYERS="${NUM_RELAYERS:=0}"
# check if the binary has genesis subcommand or not, if not, set CHAIN_GENESIS_CMD to empty
CHAIN_GENESIS_CMD=$($CHAIN_BIN 2>&1 | grep -q "genesis-related subcommands" && echo "genesis" || echo "")
jq -r ".genesis[0].mnemonic" "$KEYS_CONFIG" | $CHAIN_BIN init "$CHAIN_ID" --chain-id "$CHAIN_ID" --default-denom "$DENOM" --recover
# Add genesis keys to the keyring and self delegate initial coins
echo "Adding key...." $(jq -r ".genesis[0].name" "$KEYS_CONFIG")
jq -r ".genesis[0].mnemonic" "$KEYS_CONFIG" | $CHAIN_BIN keys add $(jq -r ".genesis[0].name" "$KEYS_CONFIG") --recover --keyring-backend="test"
$CHAIN_BIN "$CHAIN_GENESIS_CMD" add-genesis-account $($CHAIN_BIN keys show -a $(jq -r .genesis[0].name "$KEYS_CONFIG") --keyring-backend="test") "$COINS" --keyring-backend="test"
# Add faucet key to the keyring and self delegate initial coins
echo "Adding key...." $(jq -r ".faucet[0].name" "$KEYS_CONFIG")
jq -r ".faucet[0].mnemonic" "$KEYS_CONFIG" | $CHAIN_BIN keys add $(jq -r ".faucet[0].name" "$KEYS_CONFIG") --recover --keyring-backend="test"
$CHAIN_BIN "$CHAIN_GENESIS_CMD" add-genesis-account $($CHAIN_BIN keys show -a $(jq -r .faucet[0].name "$KEYS_CONFIG") --keyring-backend="test") "$COINS" --keyring-backend="test"
# Add test keys to the keyring and self delegate initial coins
echo "Adding key...." $(jq -r ".keys[0].name" "$KEYS_CONFIG")
jq -r ".keys[0].mnemonic" "$KEYS_CONFIG" | $CHAIN_BIN keys add $(jq -r ".keys[0].name" "$KEYS_CONFIG") --recover --keyring-backend="test"
$CHAIN_BIN "$CHAIN_GENESIS_CMD" add-genesis-account $($CHAIN_BIN keys show -a $(jq -r .keys[0].name "$KEYS_CONFIG") --keyring-backend="test") "$COINS" --keyring-backend="test"
if [[ $FAUCET_ENABLED == "false" && $NUM_RELAYERS -gt "-1" ]]; then
## Add relayers keys and delegate tokens
for i in $(seq 0 "$NUM_RELAYERS"); do
# Add relayer key and delegate tokens
RELAYER_KEY_NAME="$(jq -r ".relayers[$i].name" "$KEYS_CONFIG")"
echo "Adding relayer key.... $RELAYER_KEY_NAME"
jq -r ".relayers[$i].mnemonic" "$KEYS_CONFIG" | $CHAIN_BIN keys add "$RELAYER_KEY_NAME" --recover --keyring-backend="test"
$CHAIN_BIN "$CHAIN_GENESIS_CMD" add-genesis-account $($CHAIN_BIN keys show -a "$RELAYER_KEY_NAME" --keyring-backend="test") "$COINS" --keyring-backend="test"
# Add relayer-cli key and delegate tokens
RELAYER_CLI_KEY_NAME="$(jq -r ".relayers_cli[$i].name" "$KEYS_CONFIG")"
echo "Adding relayer-cli key.... $RELAYER_CLI_KEY_NAME"
jq -r ".relayers_cli[$i].mnemonic" "$KEYS_CONFIG" | $CHAIN_BIN keys add "$RELAYER_CLI_KEY_NAME" --recover --keyring-backend="test"
$CHAIN_BIN "$CHAIN_GENESIS_CMD" add-genesis-account $($CHAIN_BIN keys show -a "$RELAYER_CLI_KEY_NAME" --keyring-backend="test") "$COINS" --keyring-backend="test"
done
fi
## if faucet not enabled then add validator and relayer with index as keys and into gentx
if [[ $FAUCET_ENABLED == "false" && $NUM_VALIDATORS -gt "1" ]]; then
## Add validators key and delegate tokens
for i in $(seq 0 "$NUM_VALIDATORS"); do
VAL_KEY_NAME="$(jq -r '.validators[0].name' "$KEYS_CONFIG")-$i"
echo "Adding validator key.... $VAL_KEY_NAME"
jq -r ".validators[0].mnemonic" "$KEYS_CONFIG" | $CHAIN_BIN keys add "$VAL_KEY_NAME" --index "$i" --recover --keyring-backend="test"
$CHAIN_BIN "$CHAIN_GENESIS_CMD" add-genesis-account $($CHAIN_BIN keys show -a "$VAL_KEY_NAME" --keyring-backend="test") "$COINS" --keyring-backend="test"
done
fi
echo "Creating gentx..."
COIN=$(echo "$COINS" | cut -d ',' -f1)
# Use full validator amount to meet minimum delegation requirement (274890886240)
# Match the working init-testnet.sh: 1000000000000000000000snr = 1000000000000000000000000000usnr
VALIDATOR_AMOUNT="1000000000000000000000000000$DENOM"
$CHAIN_BIN "$CHAIN_GENESIS_CMD" gentx $(jq -r ".genesis[0].name" "$KEYS_CONFIG") "$VALIDATOR_AMOUNT" --keyring-backend="test" --chain-id "$CHAIN_ID" --gas-prices="0$DENOM"
echo "Output of gentx"
cat "$CHAIN_DIR"/config/gentx/*.json | jq
echo "Running collect-gentxs"
$CHAIN_BIN "$CHAIN_GENESIS_CMD" collect-gentxs
ls "$CHAIN_DIR"/config
# Generate VRF keypair
echo ""
echo "Generating VRF keypair..."
if ! generate_vrf_key "${CHAIN_DIR}"; then
echo "Warning: VRF key generation failed, but continuing..."
echo "Note: Multi-validator encryption features may not work without VRF keys"
fi
+177
View File
@@ -0,0 +1,177 @@
#!/bin/bash
# Cross-platform localnet script that works on all systems including Arch Linux
# This script handles Docker permission issues and provides fallback to local binary
set -eu
# Color codes for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Function to print colored output
print_color() {
color=$1
shift
echo -e "${color}$@${NC}"
}
# Detect OS
detect_os() {
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
if [ -f /etc/arch-release ]; then
echo "arch"
elif [ -f /etc/debian_version ]; then
echo "debian"
elif [ -f /etc/redhat-release ]; then
echo "redhat"
else
echo "linux"
fi
elif [[ "$OSTYPE" == "darwin"* ]]; then
echo "macos"
else
echo "unknown"
fi
}
# Check if user is in docker group
check_docker_access() {
if command -v docker >/dev/null 2>&1; then
# Try to run a simple docker command
if docker info >/dev/null 2>&1; then
return 0
else
# Check if it's a permission issue
if groups | grep -q docker; then
print_color "$YELLOW" "You're in the docker group but Docker daemon might not be running"
return 1
else
print_color "$YELLOW" "You need to be in the docker group to use Docker without sudo"
return 1
fi
fi
else
return 1
fi
}
# Check if binary exists and is accessible
check_binary() {
local binary_name="${1:-snrd}"
# Check in build directory first
if [ -x "./build/${binary_name}" ]; then
echo "./build/${binary_name}"
return 0
fi
# Check in PATH
if command -v "${binary_name}" >/dev/null 2>&1; then
echo "$(which "${binary_name}")"
return 0
fi
return 1
}
# Setup proper permissions for directories
setup_permissions() {
local home_dir="${1}"
# Ensure directory exists
mkdir -p "${home_dir}"
# Set proper ownership if running as non-root
if [ "$EUID" -ne 0 ]; then
# Make sure current user owns the directory
if [ -w "${home_dir}" ]; then
return 0
else
print_color "$YELLOW" "Setting up permissions for ${home_dir}..."
# Try to take ownership (will fail if not owner)
if ! chmod -R u+rwX "${home_dir}" 2>/dev/null; then
print_color "$RED" "Cannot set permissions on ${home_dir}. You may need to remove it manually: sudo rm -rf ${home_dir}"
return 1
fi
fi
fi
return 0
}
# Main execution
main() {
print_color "$BLUE" "=== Sonr Cross-Platform Localnet Setup ==="
# Detect OS
OS=$(detect_os)
print_color "$GREEN" "Detected OS: ${OS}"
# Set default values
export CHAIN_ID=${CHAIN_ID:-"sonrtest_1-1"}
export HOME_DIR=$(eval echo "${HOME_DIR:-"~/.sonr"}")
export BINARY=${BINARY:-"snrd"}
export BLOCK_TIME=${BLOCK_TIME:-"1000ms"}
export CLEAN=${CLEAN:-"true"}
# Decision logic for execution method
USE_METHOD=""
BINARY_PATH=""
# 1. Check if FORCE_DOCKER is set
if [[ "${FORCE_DOCKER:-false}" == "true" ]]; then
if check_docker_access; then
USE_METHOD="docker"
print_color "$GREEN" "Using Docker (forced)"
else
print_color "$RED" "FORCE_DOCKER=true but Docker is not accessible"
exit 1
fi
# 2. Check for local binary
elif BINARY_PATH=$(check_binary "${BINARY}"); then
USE_METHOD="local"
print_color "$GREEN" "Using local binary: ${BINARY_PATH}"
# 3. Try Docker as fallback
elif check_docker_access; then
USE_METHOD="docker"
print_color "$YELLOW" "No local binary found, using Docker"
else
# No method available
print_color "$RED" "Error: No execution method available!"
print_color "$YELLOW" "Please either:"
print_color "$YELLOW" " 1. Run 'make install' to build the binary"
print_color "$YELLOW" " 2. Install Docker and ensure it's running"
if [[ "${OS}" == "arch" ]]; then
print_color "$YELLOW" " On Arch Linux: sudo pacman -S docker && sudo systemctl start docker"
print_color "$YELLOW" " Add yourself to docker group: sudo usermod -aG docker $USER"
fi
exit 1
fi
# Setup permissions for home directory
if ! setup_permissions "${HOME_DIR}"; then
print_color "$RED" "Failed to setup permissions"
exit 1
fi
# Export the method for test_node.sh to use
if [[ "${USE_METHOD}" == "docker" ]]; then
export FORCE_DOCKER=true
else
export FORCE_DOCKER=false
# Add build directory to PATH if using local binary from build/
if [[ "${BINARY_PATH}" == "./build/"* ]]; then
export PATH="$(pwd)/build:${PATH}"
fi
fi
# Run the actual test node script
print_color "$BLUE" "Starting localnet with ${USE_METHOD} method..."
bash scripts/test_node.sh
}
# Run main function
main "$@"
+331
View File
@@ -0,0 +1,331 @@
#!/bin/bash
set -eu
# clear
# Detect git state and determine appropriate comparison base
git_comparison_base() {
local current_branch=$(git rev-parse --abbrev-ref HEAD)
# Check for uncommitted changes (staged or unstaged)
if [[ -n "$(git status --porcelain)" ]]; then
# Development mode - compare against last commit
echo "HEAD"
return
fi
# Check if we're on master/main branch
if [[ "$current_branch" == "master" ]] || [[ "$current_branch" == "main" ]]; then
# On master - compare against last tag
local last_tag=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
if [[ -n "$last_tag" ]]; then
echo "$last_tag"
else
# No tags exist, compare against first commit
echo "$(git rev-list --max-parents=0 HEAD)"
fi
return
fi
# On feature branch with clean state - compare against master
echo "master"
}
# Get current git context for display
git_context() {
local base=$(git_comparison_base)
local current_branch=$(git rev-parse --abbrev-ref HEAD)
local has_changes=$(git status --porcelain | wc -l)
if [[ "$has_changes" -gt 0 ]]; then
echo "Development mode: comparing against HEAD (last commit)"
elif [[ "$current_branch" == "master" ]] || [[ "$current_branch" == "main" ]]; then
echo "Master branch: comparing against $base"
else
echo "Feature branch: comparing against master"
fi
}
changed_files() {
local base=$(git_comparison_base)
if [[ "$base" == "HEAD" ]]; then
# In development mode - show uncommitted changes
git diff --name-only HEAD
git diff --cached --name-only
git ls-files --others --exclude-standard
else
# Compare against determined base
git diff --name-only "$base" "$(git rev-parse HEAD)"
fi | sort -u
}
changed_scopes() {
local changed_files=$(changed_files)
local context=$(git_context)
echo "🔍 Changed Files by Scope"
echo "========================="
echo "📍 $context"
echo ""
# Process each scope
yq eval '.[] | @json' .github/scopes.yml | while IFS= read -r scope_obj; do
local scope_name=$(echo "$scope_obj" | jq -r '.name')
local patterns=$(echo "$scope_obj" | jq -r '.include[]' | sed 's|^\./||; s|/\*\*$||')
local matched_files=""
# Find matching files for all patterns of this scope
for pattern in $patterns; do
while IFS= read -r file; do
[[ -n "$file" ]] && [[ "$file" == "$pattern"* ]] && matched_files+="$file\n"
done <<<"$changed_files"
done
# Display if there are matches
if [[ -n "$matched_files" ]]; then
local unique_count=$(echo -e "$matched_files" | sort -u | grep -c '^' || echo 0)
echo ""
echo "📦 $scope_name [$unique_count files]"
# Group files by directory
echo -e "$matched_files" | sort -u | while IFS= read -r file; do
[[ -n "$file" ]] || continue
# Indent based on directory depth
local depth=$(echo "$file" | tr -cd '/' | wc -c)
local indent=""
for ((i = 0; i < depth; i++)); do
indent=" $indent"
done
# Show just the filename with smart tree characters
local basename=$(basename "$file")
local dirname=$(dirname "$file")
if [[ "$dirname" != "." ]]; then
echo " 📁 $dirname/"
echo " └── $basename"
else
echo " └── $file"
fi
done | sort -u # Remove duplicate directory listings
fi
done
}
success() {
gum log --structured "$1" --prefix "✅" --prefix.foreground "#00ff00"
}
error() {
gum log --structured "$1" --prefix "❌" --prefix.foreground "#ff0000"
}
info() {
gum log --structured --prefix "📍" --prefix.foreground "#00ffff" "$1"
}
header() {
local title="$1"
gum style --border-foreground 240 --border double --align center --padding "0 1" "$title"
echo "" | gum format
}
separator() {
echo "---" | gum format
}
list_item() {
local item="$1"
echo "- $item" | gum format
}
devbox_run() {
local command="$1"
local action=$(echo "$command" | cut -f1 -d: | tr '[:upper:]' '[:lower:]')
local scope=$(echo "$command" | cut -f2 -d: | tr '[:upper:]' '[:lower:]')
local title="Executing devbox run $action:$scope..."
gum spin --show-error --spinner meter --title "$title" -- devbox run "$command"
success "$scope finished $action"
}
install() {
header "Install"
gum spin --show-error --spinner pulse --title "Installing pnpm..." -- pnpm install --frozen-lockfile
gum spin --show-error --spinner pulse --title "Installing Go..." -- go mod download
info "pnpm(10.14.0)"
info "go(1.24.7)"
separator
}
build_all() {
header "Build"
devbox_run "build:auth"
devbox_run "build:dash"
devbox_run "build:core"
devbox_run "build:com"
devbox_run "build:es"
devbox_run "build:hway"
devbox_run "build:motr"
devbox_run "build:pkl"
devbox_run "build:sdk"
devbox_run "build:ui"
devbox_run "build:vault"
separator
}
test_all() {
header "Test"
devbox_run "test:auth"
devbox_run "test:dash"
devbox_run "test:core"
devbox_run "test:com"
devbox_run "test:es"
devbox_run "test:hway"
devbox_run "test:motr"
devbox_run "test:pkl"
devbox_run "test:sdk"
devbox_run "test:ui"
devbox_run "test:vault"
separator
}
release_all() {
header "Release"
# devbox_run "release:auth"
# devbox_run "release:dash"
devbox_run "release:core"
devbox_run "release:com"
devbox_run "release:es"
devbox_run "release:hway"
devbox_run "release:motr"
devbox_run "release:pkl"
devbox_run "release:sdk"
devbox_run "release:ui"
devbox_run "release:vault"
separator
}
snapshot_all() {
header "Snapshot"
devbox_run "snapshot:core"
devbox_run "snapshot:hway"
devbox_run "snapshot:motr"
devbox_run "snapshot:vault"
separator
}
test_scopes() {
for scope in $(affected_scopes); do
# Check if the test script exists in devbox.json
if grep -q "\"test:$scope\":" devbox.json 2>/dev/null; then
echo "Testing scope: $scope"
devbox run "test:$scope"
else
echo "Skipping test for scope: $scope (no test script defined)"
fi
done
}
build_scopes() {
for scope in $(affected_scopes); do
# Check if the build script exists in devbox.json
if grep -q "\"build:$scope\":" devbox.json 2>/dev/null; then
echo "Building scope: $scope"
devbox run "build:$scope"
else
echo "Skipping build for scope: $scope (no build script defined)"
fi
done
}
release_scopes() {
for scope in $(affected_scopes); do
# Check if the release script exists in devbox.json
if grep -q "\"release:$scope\":" devbox.json 2>/dev/null; then
echo "Releasing scope: $scope"
devbox run "release:$scope"
else
echo "Skipping release for scope: $scope (no release script defined)"
fi
done
}
snapshot_scopes() {
for scope in $(affected_scopes); do
# Check if the snapshot script exists in devbox.json
if grep -q "\"snapshot:$scope\":" devbox.json 2>/dev/null; then
echo "Creating snapshot for scope: $scope"
devbox run "snapshot:$scope"
else
echo "Skipping snapshot for scope: $scope (no snapshot script defined)"
fi
done
}
affected_scopes() {
local verbose="${1:-false}"
local changed_files=$(changed_files)
if [[ "$verbose" == "true" ]] || [[ "$verbose" == "-v" ]]; then
echo "📍 $(git_context)" >&2
echo "" >&2
fi
yq eval -o=json '.[]' .github/scopes.yml | jq -r --arg files "$changed_files" '
select(.include[] as $pattern |
$files | split("\n")[] |
startswith($pattern | sub("^\\./"; "") | sub("/\\*\\*$"; ""))
) |
.name
' | sort -u
}
main() {
cmd="$1"
shift || true # Allow shifting even if no more args
case "$cmd" in
"build-all")
build_all
;;
"test-all")
test_all
;;
"release-all")
release_all
;;
"snapshot-all")
snapshot_all
;;
"build-scopes")
build_scopes
;;
"test-scopes")
test_scopes
;;
"release-scopes")
release_scopes
;;
"snapshot-scopes")
snapshot_scopes
;;
"install-pnpm")
install_pnpm
;;
"install-go")
install_go
;;
"install")
install
;;
*)
echo "Unknown command: $cmd"
exit 1
;;
esac
}
main "$@"
+336
View File
@@ -0,0 +1,336 @@
#!/bin/bash
set -eu
# Detect git state and determine appropriate comparison base
git_comparison_base() {
local current_branch=$(git rev-parse --abbrev-ref HEAD)
# Check for uncommitted changes (staged or unstaged)
if [[ -n "$(git status --porcelain)" ]]; then
# Development mode - compare against last commit
echo "HEAD"
return
fi
# Check if we're on master/main branch
if [[ "$current_branch" == "master" ]] || [[ "$current_branch" == "main" ]]; then
# On master - compare against last tag
local last_tag=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
if [[ -n "$last_tag" ]]; then
echo "$last_tag"
else
# No tags exist, compare against first commit
echo "$(git rev-list --max-parents=0 HEAD)"
fi
return
fi
# On feature branch with clean state - compare against master
echo "master"
}
# Get development mode status
is_development_mode() {
if [[ -n "$(git status --porcelain)" ]]; then
echo "true"
else
echo "false"
fi
}
# Get current git context for display
git_context() {
local base=$(git_comparison_base)
local current_branch=$(git rev-parse --abbrev-ref HEAD)
local has_changes=$(git status --porcelain | wc -l)
if [[ "$has_changes" -gt 0 ]]; then
echo "Development mode: comparing against HEAD (last commit)"
elif [[ "$current_branch" == "master" ]] || [[ "$current_branch" == "main" ]]; then
echo "Master branch: comparing against $base"
else
echo "Feature branch: comparing against master"
fi
}
default_branch() {
# This function is kept for backward compatibility
echo "master"
}
changed_files() {
local base=$(git_comparison_base)
if [[ "$base" == "HEAD" ]]; then
# In development mode - show uncommitted changes
git diff --name-only HEAD
git diff --cached --name-only
git ls-files --others --exclude-standard
else
# Compare against determined base
git diff --name-only "$base" "$(git rev-parse HEAD)"
fi | sort -u
}
changed_scopes() {
local changed_files=$(changed_files)
local context=$(git_context)
echo "🔍 Changed Files by Scope"
echo "========================="
echo "📍 $context"
echo ""
# Process each scope
yq eval '.[] | @json' .github/scopes.yml | while IFS= read -r scope_obj; do
local scope_name=$(echo "$scope_obj" | jq -r '.name')
local patterns=$(echo "$scope_obj" | jq -r '.include[]' | sed 's|^\./||; s|/\*\*$||')
local matched_files=""
# Find matching files for all patterns of this scope
for pattern in $patterns; do
while IFS= read -r file; do
[[ -n "$file" ]] && [[ "$file" == "$pattern"* ]] && matched_files+="$file\n"
done <<<"$changed_files"
done
# Display if there are matches
if [[ -n "$matched_files" ]]; then
local unique_count=$(echo -e "$matched_files" | sort -u | grep -c '^' || echo 0)
echo ""
echo "📦 $scope_name [$unique_count files]"
# Group files by directory
echo -e "$matched_files" | sort -u | while IFS= read -r file; do
[[ -n "$file" ]] || continue
# Indent based on directory depth
local depth=$(echo "$file" | tr -cd '/' | wc -c)
local indent=""
for ((i = 0; i < depth; i++)); do
indent=" $indent"
done
# Show just the filename with smart tree characters
local basename=$(basename "$file")
local dirname=$(dirname "$file")
if [[ "$dirname" != "." ]]; then
echo " 📁 $dirname/"
echo " └── $basename"
else
echo " └── $file"
fi
done | sort -u # Remove duplicate directory listings
fi
done
}
changed_scopes_diff() {
local changed_files=$(changed_files)
local base_branch=$(default_branch)
local max_lines="${1:-10}" # Max diff lines to show per file
echo "🔍 Changed Files with Diffs"
echo "==========================="
# Process each scope
yq eval '.[] | @json' .github/scopes.yml | while IFS= read -r scope_obj; do
local scope_name=$(echo "$scope_obj" | jq -r '.name')
local patterns=$(echo "$scope_obj" | jq -r '.include[]' | sed 's|^\./||; s|/\*\*$||')
local matched_files=""
# Find matching files
for pattern in $patterns; do
while IFS= read -r file; do
[[ -n "$file" ]] && [[ "$file" == "$pattern"* ]] && matched_files+="$file\n"
done <<<"$changed_files"
done
if [[ -n "$matched_files" ]]; then
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📦 $scope_name"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo -e "$matched_files" | sort -u | while IFS= read -r file; do
[[ -n "$file" ]] || continue
echo ""
echo "┌─ 📄 $file"
echo "├─────────────────────────────────"
# Show the diff with context
git diff --unified=2 "$base_branch...HEAD" -- "$file" |
tail -n +5 |
head -n "$max_lines" |
while IFS= read -r line; do
case "$line" in
@@*)
echo "$(tput setaf 6)$line$(tput sgr0)"
;;
+*)
echo "$(tput setaf 2)$line$(tput sgr0)"
;;
-*)
echo "$(tput setaf 1)$line$(tput sgr0)"
;;
*)
echo "$line"
;;
esac
done
# Check if diff was truncated
local full_diff_lines=$(git diff "$base_branch...HEAD" -- "$file" | wc -l)
if [[ $full_diff_lines -gt $max_lines ]]; then
echo "│ ... ($(($full_diff_lines - $max_lines)) more lines)"
fi
echo "└─────────────────────────────────"
done
fi
done
}
affected_scopes() {
local verbose="${1:-false}"
local changed_files=$(changed_files)
if [[ "$verbose" == "true" ]] || [[ "$verbose" == "-v" ]]; then
echo "📍 $(git_context)" >&2
echo "" >&2
fi
yq eval -o=json '.[]' .github/scopes.yml | jq -r --arg files "$changed_files" '
select(.include[] as $pattern |
$files | split("\n")[] |
startswith($pattern | sub("^\\./"; "") | sub("/\\*\\*$"; ""))
) |
.name
' | sort -u
}
current_issue() {
local branch=$(git rev-parse --abbrev-ref HEAD)
local feature_part=$(echo "$branch" | cut -f2 -d'/')
local result=$(gh issue ls | rg -i "$feature_part" | cut -f1 | head -n1)
if [[ -z "$result" ]]; then
local middle_part=$(echo "$feature_part" | cut -f2 -d'-')
if [[ -n "$middle_part" ]]; then
result=$(gh issue ls | rg -i "$middle_part" | cut -f1 | head -n1)
fi
fi
echo "$result"
}
current_branch() {
git rev-parse --abbrev-ref HEAD
}
current_pr() {
gh pr ls --json headRefName,number --jq '.[] | {number: .number, branch: .headRefName}' | rg "$(git rev-parse --abbrev-ref HEAD)" | jq '.number'
}
current_milestone() {
gh issue view "$(current_issue)" --json milestone --jq '.milestone'
}
final_issue() {
local issue_num=$(current_issue)
if [[ -z "$issue_num" ]]; then
echo "false"
return
fi
# Get milestone details
local milestone_data=$(gh issue view "$issue_num" --json milestone)
local milestone_title=$(echo "$milestone_data" | jq -r '.milestone.title // empty')
local milestone_number=$(echo "$milestone_data" | jq -r '.milestone.number // empty')
if [[ -z "$milestone_title" ]]; then
echo "false"
return
fi
# Get all open issues in the milestone
local open_issues=$(gh issue list --milestone "$milestone_title" --state open --json number,title)
local open_count=$(echo "$open_issues" | jq 'length')
# Debug output (optional - remove if not needed)
if [[ "${DEBUG:-}" == "true" ]]; then
echo "Current issue: #$issue_num" >&2
echo "Milestone: $milestone_title" >&2
echo "Open issues in milestone: $open_count" >&2
echo "$open_issues" | jq -r '.[] | "#\(.number): \(.title)"' >&2
fi
# Return true only if exactly 1 issue remains
[[ "$open_count" -eq 1 ]] && echo "true" || echo "false"
}
# Validate that we're on the default branch (master/main)
# Returns exit 1 if not on default branch - useful for pre-bump hooks
validate_default_branch() {
local current_branch=$(git rev-parse --abbrev-ref HEAD)
if [[ "$current_branch" == "master" ]] || [[ "$current_branch" == "main" ]]; then
echo "✅ On default branch: $current_branch"
return 0
else
echo "❌ Error: Not on default branch (master/main)"
echo " Current branch: $current_branch"
echo " Please switch to master/main before bumping versions"
return 1
fi
}
main() {
cmd="$1"
shift || true # Allow shifting even if no more args
case "$cmd" in
"git-context")
echo "$(git_context)"
;;
"validate-default-branch")
validate_default_branch
exit $?
;;
"affected-scopes")
echo "$(affected_scopes "$@")"
;;
"changed-files")
echo "$(changed_files)"
;;
"changed-scopes")
echo "$(changed_scopes)"
;;
"changed-scopes-diff")
echo "$(changed_scopes_diff)"
;;
"current-branch")
echo "$(current_branch)"
;;
"current-issue")
echo "$(current_issue)"
;;
"current-milestone")
echo "$(current_milestone)"
;;
"current-pr")
echo "$(current_pr)"
;;
"final-issue")
echo "$(final_issue)"
;;
*)
echo "Unknown command: $cmd"
exit 1
;;
esac
}
main "$@"
+17
View File
@@ -0,0 +1,17 @@
#!/bin/bash
set -e
# Get script directory and project root
BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
# Variables passed from commitizen
IS_INITIAL=$CZ_POST_IS_INITIAL
CURRENT_TAG=$CZ_POST_CURRENT_TAG_VERSION
# Check if we're not on release branch
if [[ "$BRANCH" != "master" ]] && [[ "$BRANCH" != "main" ]]; then
echo "❌ Error: Cannot bump versions on feature branch"
echo " Please switch to master/main branch and try again."
exit 1
fi
+74
View File
@@ -0,0 +1,74 @@
#!/bin/bash
set -e
# Cleanup function to discard CHANGELOG.md changes on failure
cleanup_on_error() {
local exit_code=$?
if [[ $exit_code -ne 0 ]]; then
echo "❌ Error occurred during version bump (exit code: $exit_code)"
# Find all CHANGELOG.md files with changes
local changed_changelogs=$(git diff --name-only | grep "CHANGELOG.md" || true)
local staged_changelogs=$(git diff --cached --name-only | grep "CHANGELOG.md" || true)
# Discard unstaged changes
if [[ -n "$changed_changelogs" ]]; then
echo "🧹 Discarding local changes to CHANGELOG.md files..."
while IFS= read -r file; do
if [[ -n "$file" ]]; then
echo " Reverting: $file"
git checkout -- "$file" 2>/dev/null || true
fi
done <<< "$changed_changelogs"
echo "✅ Unstaged CHANGELOG.md changes discarded"
fi
# Discard staged changes
if [[ -n "$staged_changelogs" ]]; then
echo "🧹 Unstaging and discarding staged CHANGELOG.md files..."
while IFS= read -r file; do
if [[ -n "$file" ]]; then
echo " Reverting: $file"
git reset HEAD "$file" 2>/dev/null || true
git checkout -- "$file" 2>/dev/null || true
fi
done <<< "$staged_changelogs"
echo "✅ Staged CHANGELOG.md changes discarded"
fi
if [[ -z "$changed_changelogs" ]] && [[ -z "$staged_changelogs" ]]; then
echo "️ No CHANGELOG.md changes to discard"
fi
fi
exit $exit_code
}
# Set trap to cleanup on any error
trap cleanup_on_error EXIT
# Get script directory and project root
BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
NEW_TAG=$CZ_PRE_NEW_TAG_VERSION
IS_NEW=$CZ_PRE_IS_INITIAL
CHANGELOG=$CZ_PRE_CHANGELOG_FILE_NAME
ORIGIN_TAGS=$(git tag -l)
# Check if we're not on release branch
if [[ "$BRANCH" != "master" ]] && [[ "$BRANCH" != "main" ]]; then
echo "❌ Error: Cannot bump versions on feature branch"
echo " Please switch to master/main branch and try again."
exit 1
fi
# Verify next tag is not already present
if echo "$ORIGIN_TAGS" | grep -q "$NEW_TAG"; then
echo "❌ Error: Tag $NEW_TAG already exists"
echo " Please choose a different tag name."
exit 1
fi
# Create CHANGELOG.md if it doesn't exist
if [ ! -f "$CHANGELOG" ]; then
echo "⚠️ Warning: CHANGELOG.md not found, creating new file."
touch "$CHANGELOG"
fi
+17
View File
@@ -0,0 +1,17 @@
#!/bin/bash
set -e
# Get script directory and project root
BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
# Variables passed from commitizen
IS_INITIAL=$CZ_POST_IS_INITIAL
CURRENT_TAG=$CZ_POST_CURRENT_TAG_VERSION
# Check if we're not on release branch
if [[ "$BRANCH" != "master" ]] && [[ "$BRANCH" != "main" ]]; then
echo "❌ Error: Cannot bump versions on feature branch"
echo " Please switch to master/main branch and try again."
exit 1
fi
+17
View File
@@ -0,0 +1,17 @@
#!/bin/bash
set -e
# Get script directory and project root
BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
# Variables passed from commitizen
IS_INITIAL=$CZ_POST_IS_INITIAL
CURRENT_TAG=$CZ_POST_CURRENT_TAG_VERSION
# Check if we're not on release branch
if [[ "$BRANCH" != "master" ]] && [[ "$BRANCH" != "main" ]]; then
echo "❌ Error: Cannot bump versions on feature branch"
echo " Please switch to master/main branch and try again."
exit 1
fi
+254 -72
View File
@@ -7,85 +7,267 @@ detect_platform() {
OS=$(uname -s)
ARCH=$(uname -m)
# Normalize OS names to match GitHub release naming
case "${OS}" in
Darwin) OS_NAME="darwin" ;;
Linux) OS_NAME="linux" ;;
MINGW* | MSYS* | CYGWIN*) OS_NAME="windows" ;;
*)
echo "Unsupported OS: ${OS}"
exit 1
;;
esac
# Normalize architecture names
case "${ARCH}" in
x86_64) ARCH="amd64" ;;
aarch64 | arm64) ARCH="arm64" ;;
esac
}
# Function to get latest release version
get_latest_version() {
LATEST_VERSION=$(curl -s https://api.github.com/repos/sonr-io/snrd/releases/latest | grep "tag_name" | cut -d '"' -f 4)
LATEST_VERSION=${LATEST_VERSION#v} # Remove 'v' prefix
}
# Function to install binaries to current directory
install_tar() {
local OS_NAME=$1
echo "Installing Sonr for ${OS_NAME} (${ARCH})..."
DOWNLOAD_URL="https://github.com/sonr-io/snrd/releases/download/v${LATEST_VERSION}/sonr_${LATEST_VERSION}_${OS_NAME}_${ARCH}.tar.gz"
# Download and extract
echo "Downloading Sonr..."
curl -L "${DOWNLOAD_URL}" -o sonr.tar.gz
tar -xzf sonr.tar.gz
rm sonr.tar.gz
chmod +x sonrd hway
echo "Binaries 'sonrd' and 'hway' have been extracted to the current directory"
echo
echo "To make them available system-wide, you can move them to /usr/local/bin with:"
echo "sudo mv sonrd hway /usr/local/bin/"
echo
echo "Or move them to your personal bin directory with:"
echo "mkdir -p ~/.local/bin"
echo "mv sonrd hway ~/.local/bin/"
echo "Then add ~/.local/bin to your PATH if it's not already there"
}
# Function to install on Debian/Ubuntu
install_debian() {
echo "Installing Sonr for Debian/Ubuntu (${ARCH})..."
SONRD_URL="https://github.com/sonr-io/snrd/releases/download/v${LATEST_VERSION}/sonrd_${LATEST_VERSION}_${ARCH}.deb"
HWAY_URL="https://github.com/sonr-io/snrd/releases/download/v${LATEST_VERSION}/hway_${LATEST_VERSION}_${ARCH}.deb"
# Download packages
TMP_DIR=$(mktemp -d)
curl -L "${SONRD_URL}" -o "${TMP_DIR}/sonrd.deb"
curl -L "${HWAY_URL}" -o "${TMP_DIR}/hway.deb"
# Install packages
sudo dpkg -i "${TMP_DIR}/sonrd.deb"
sudo dpkg -i "${TMP_DIR}/hway.deb"
# Cleanup
rm -rf "${TMP_DIR}"
echo "Sonr has been installed system-wide"
}
main() {
detect_platform
get_latest_version
case "${OS}" in
Darwin)
install_tar "Darwin"
;;
Linux)
if [[ -f /etc/debian_version ]]; then
install_debian
else
install_tar "Linux"
fi
;;
*)
echo "Unsupported operating system: ${OS}"
echo "Unsupported architecture: ${ARCH}"
exit 1
;;
esac
}
main
# Function to check if we can build locally
can_build_locally() {
# Check if we're in the sonr project directory
if [[ -f "Makefile" ]] && [[ -f "go.mod" ]] && grep -q "module github.com/sonr-io/sonr" go.mod 2>/dev/null; then
return 0
fi
return 1
}
# Function to build locally
build_locally() {
local INSTALL_DIR="$1"
echo "Building Sonr locally..."
# Check if make and go are available
if ! command -v make >/dev/null 2>&1; then
echo "Error: make is required to build locally"
exit 1
fi
if ! command -v go >/dev/null 2>&1; then
echo "Error: Go is required to build locally"
exit 1
fi
# Build binaries
echo "Building snrd..."
make build || {
echo "Error: Failed to build snrd"
exit 1
}
echo "Building motr..."
make motr || {
echo "Error: Failed to build motr"
exit 1
}
# Copy binaries to install directory
cp build/snrd "${INSTALL_DIR}/" || {
echo "Error: Failed to copy snrd"
exit 1
}
cp build/motr.wasm "${INSTALL_DIR}/" || {
echo "Error: Failed to copy motr.wasm"
exit 1
}
# Make binaries executable
chmod +x "${INSTALL_DIR}/snrd"
echo "Binaries built and installed successfully to ${INSTALL_DIR}"
}
# Function to get latest release version
get_latest_version() {
RELEASE_DATA=$(curl -s https://api.github.com/repos/sonr-io/sonr/releases/latest)
# Check if API returned an error (no releases available or private repo)
if echo "${RELEASE_DATA}" | grep -q '"message": "Not Found"'; then
if can_build_locally; then
echo "No public releases found, building locally..."
return 1
else
echo "Error: No releases found for sonr-io/sonr"
echo "Please build and install from source:"
echo " git clone https://github.com/sonr-io/sonr.git"
echo " cd sonr"
echo " ./scripts/install.sh"
exit 1
fi
fi
LATEST_VERSION=$(echo "${RELEASE_DATA}" | grep "tag_name" | cut -d '"' -f 4)
if [[ -z "${LATEST_VERSION}" ]]; then
echo "Error: Could not determine latest version"
if can_build_locally; then
echo "Falling back to local build..."
return 1
fi
exit 1
fi
LATEST_VERSION=${LATEST_VERSION#v} # Remove 'v' prefix
return 0
}
# Function to install binaries
install_binaries() {
local INSTALL_DIR="${1:-$(pwd)}"
# Check if we have a version from releases
if [[ -n "${LATEST_VERSION}" ]]; then
echo "Installing Sonr v${LATEST_VERSION} for ${OS_NAME} (${ARCH}) to ${INSTALL_DIR}..."
# Use dl.sonr.io CDN for faster downloads
BASE_URL="https://dl.sonr.io/v${LATEST_VERSION}"
# Download snrd binary
echo "Downloading snrd..."
if [[ ${OS_NAME} == "windows" ]]; then
echo "Error: snrd does not support Windows"
exit 1
else
if ! curl -L "${BASE_URL}/snrd_${OS_NAME}_${ARCH}" -o "${INSTALL_DIR}/snrd" -f; then
echo "Warning: Failed to download from CDN, trying GitHub releases..."
# Fallback to GitHub releases
GITHUB_URL="https://github.com/sonr-io/sonr/releases/download/v${LATEST_VERSION}"
if ! curl -L "${GITHUB_URL}/snrd_${OS_NAME}_${ARCH}" -o "${INSTALL_DIR}/snrd" -f; then
echo "Error: Failed to download snrd binary from both CDN and GitHub"
exit 1
fi
fi
fi
# Download motr.wasm (platform independent)
echo "Downloading motr.wasm..."
if ! curl -L "${BASE_URL}/motr.wasm" -o "${INSTALL_DIR}/motr.wasm" -f; then
echo "Warning: Failed to download from CDN, trying GitHub releases..."
# Fallback to GitHub releases
GITHUB_URL="https://github.com/sonr-io/sonr/releases/download/v${LATEST_VERSION}"
if ! curl -L "${GITHUB_URL}/motr.wasm" -o "${INSTALL_DIR}/motr.wasm" -f; then
echo "Error: Failed to download motr.wasm from both CDN and GitHub"
exit 1
fi
fi
# Make binaries executable
chmod +x "${INSTALL_DIR}/snrd"
echo "Binaries installed successfully to ${INSTALL_DIR}"
else
# Fall back to local build
build_locally "${INSTALL_DIR}"
fi
echo
echo "Available commands:"
echo " snrd - Blockchain daemon"
echo " motr.wasm - WebAssembly enclave"
echo
echo "Quick start:"
echo " snrd --help # Show available commands"
echo " snrd start # Start the blockchain node"
}
# Function to install system-wide
install_system() {
if [[ ${EUID} -eq 0 ]]; then
INSTALL_DIR="/usr/local/bin"
else
echo "Installing to /usr/local/bin requires sudo privileges..."
sudo -v || {
echo "Sudo access required for system-wide installation"
exit 1
}
INSTALL_DIR="/usr/local/bin"
# Create temporary directory and install there first
TMP_DIR=$(mktemp -d)
install_binaries "${TMP_DIR}"
# Move to system directory with sudo
sudo mv "${TMP_DIR}/"* "${INSTALL_DIR}/"
rm -rf "${TMP_DIR}"
echo "Binaries installed system-wide to ${INSTALL_DIR}"
return
fi
install_binaries "${INSTALL_DIR}"
}
# Function to install to user directory
install_user() {
USER_BIN_DIR="${HOME}/.local/bin"
mkdir -p "${USER_BIN_DIR}"
install_binaries "${USER_BIN_DIR}"
# Check if user bin is in PATH
if [[ ":${PATH}:" != *":${USER_BIN_DIR}:"* ]]; then
echo
echo "WARNING: ${USER_BIN_DIR} is not in your PATH"
echo "Add the following line to your shell profile (~/.bashrc, ~/.zshrc, etc.):"
echo 'export PATH="$HOME/.local/bin:$PATH"'
echo
echo "Then restart your terminal or run: source ~/.bashrc"
fi
}
main() {
detect_platform
# Try to get latest version from releases, but don't fail if not available
if ! get_latest_version; then
# get_latest_version returned 1, meaning no releases but we can build locally
LATEST_VERSION=""
fi
# Parse command line arguments
case "${1-}" in
--system | -s)
install_system
;;
--user | -u)
install_user
;;
--current | -c)
install_binaries "$(pwd)"
;;
--help | -h)
echo "Sonr Installation Script"
echo
echo "Usage: $0 [OPTIONS]"
echo
echo "Options:"
echo " --system, -s Install system-wide to /usr/local/bin (requires sudo)"
echo " --user, -u Install to ~/.local/bin (user directory)"
echo " --current, -c Install to current directory"
echo " --help, -h Show this help message"
echo
echo "If no option is specified, defaults to --user installation"
echo
if can_build_locally; then
echo "Note: No public releases found, will build from source"
fi
exit 0
;;
"")
# Default to user installation
install_user
;;
*)
echo "Unknown option: $1"
echo "Use --help for usage information"
exit 1
;;
esac
}
main "$@"
-12
View File
@@ -1,12 +0,0 @@
#!/usr/bin/env bash
set -e
SOURCE=$1
OUTPUT=$2
ROOT_DIR=$(git rev-parse --show-toplevel)
cd $ROOT_DIR
mkdir -p $OUTPUT
pkl eval package://pkg.pkl-lang.org/pkl-pantry/org.json_schema.contrib@1.0.0#/generate.pkl -m . -p source="$SOURCE" -p output="$OUTPUT"
Regular → Executable
+21 -22
View File
@@ -2,21 +2,20 @@
set -e
GO_MOD_PACKAGE="github.com/sonr-io/snrd"
ROOT_DIR=$(git rev-parse --show-toplevel)
GO_MOD_PACKAGE="github.com/sonr-io/sonr"
echo "Generating gogo proto code"
cd proto
proto_dirs=$(find . -path -prune -o -name '*.proto' -print0 | xargs -0 -n1 dirname | sort | uniq)
for dir in $proto_dirs; do
for file in $(find "${dir}" -maxdepth 1 -name '*.proto'); do
# this regex checks if a proto file has its go_package set to github.com/strangelove-ventures/poa/...
# gogo proto files SHOULD ONLY be generated if this is false
# we don't want gogo proto to run for proto files which are natively built for google.golang.org/protobuf
if grep -q "option go_package" "$file" && grep -H -o -c "option go_package.*$GO_MOD_PACKAGE/api" "$file" | grep -q ':0$'; then
buf generate --template buf.gen.gogo.yaml $file
fi
done
for dir in ${proto_dirs}; do
for file in $(find "${dir}" -maxdepth 1 -name '*.proto'); do
# this regex checks if a proto file has its go_package set to github.com/strangelove-ventures/poa/...
# gogo proto files SHOULD ONLY be generated if this is false
# we don't want gogo proto to run for proto files which are natively built for google.golang.org/protobuf
if grep -q "option go_package" "${file}" && grep -H -o -c "option go_package.*${GO_MOD_PACKAGE}/api" "${file}" | grep -q ':0$'; then
buf generate --template buf.gen.gogo.yaml "${file}"
fi
done
done
echo "Generating pulsar proto code"
@@ -24,28 +23,28 @@ buf generate --template buf.gen.pulsar.yaml
cd ..
cp -r $GO_MOD_PACKAGE/* ./
cp -r "${GO_MOD_PACKAGE}"/* ./
rm -rf github.com
# Copy files over for dep injection
rm -rf api && mkdir api
custom_modules=$(find . -name 'module' -type d -not -path "./proto/*" -not -path "./.cache/*")
custom_modules=$(find . -name 'module' -type d -not -path "./proto/*" -not -path "./.cache/*" -not -path "./node_modules/*" -not -path "./packages/*")
# get the 1 up directory (so ./cosmos/mint/module becomes ./cosmos/mint)
# remove the relative path starter from base namespaces. so ./cosmos/mint becomes cosmos/mint
base_namespace=$(echo $custom_modules | sed -e 's|/module||g' | sed -e 's|\./||g')
base_namespace=$(echo "${custom_modules}" | sed -e 's|/module||g' | sed -e 's|\./||g')
# echo "Base namespace: $base_namespace"
for module in $base_namespace; do
echo " [+] Moving: ./$module to ./api/$module"
for module in ${base_namespace}; do
echo " [+] Moving: ./${module} to ./api/${module}"
mkdir -p api/$module
mkdir -p api/"${module}"
mv $module/* ./api/$module/
mv "${module}"/* ./api/"${module}"/
# # incorrect reference to the module for coins
find api/$module -type f -name '*.go' -exec sed -i -e 's|types "github.com/cosmos/cosmos-sdk/types"|types "cosmossdk.io/api/cosmos/base/v1beta1"|g' {} \;
find api/$module -type f -name '*.go' -exec sed -i -e 's|types1 "github.com/cosmos/cosmos-sdk/x/bank/types"|types1 "cosmossdk.io/api/cosmos/bank/v1beta1"|g' {} \;
# # incorrect reference to the module for coins
find api/"${module}" -type f -name '*.go' -exec sed -i -e 's|types "github.com/cosmos/cosmos-sdk/types"|types "cosmossdk.io/api/cosmos/base/v1beta1"|g' {} \;
find api/"${module}" -type f -name '*.go' -exec sed -i -e 's|types1 "github.com/cosmos/cosmos-sdk/x/bank/types"|types1 "cosmossdk.io/api/cosmos/bank/v1beta1"|g' {} \;
rm -rf $module
rm -rf "${module}"
done
+263
View File
@@ -0,0 +1,263 @@
#!/bin/bash
# Setup script for running Sonr localnet on various systems
# Supports: Arch Linux, Ubuntu/Debian, RedHat/Fedora, macOS
set -e
# Color codes
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
MAGENTA='\033[0;35m'
NC='\033[0m'
print_color() {
color=$1
shift
echo -e "${color}$@${NC}"
}
# Detect OS and distribution
detect_os() {
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
if [ -f /etc/arch-release ]; then
echo "arch"
elif [ -f /etc/debian_version ]; then
echo "debian"
elif [ -f /etc/redhat-release ]; then
echo "redhat"
elif [ -f /etc/alpine-release ]; then
echo "alpine"
else
echo "linux"
fi
elif [[ "$OSTYPE" == "darwin"* ]]; then
echo "macos"
else
echo "unknown"
fi
}
# Install Docker on different systems
install_docker() {
local os=$1
print_color $BLUE "Installing Docker for ${os}..."
case $os in
arch)
print_color $YELLOW "Installing Docker on Arch Linux..."
sudo pacman -Sy --noconfirm docker docker-compose
sudo systemctl enable docker
sudo systemctl start docker
;;
debian)
print_color $YELLOW "Installing Docker on Debian/Ubuntu..."
sudo apt-get update
sudo apt-get install -y docker.io docker-compose
sudo systemctl enable docker
sudo systemctl start docker
;;
redhat)
print_color $YELLOW "Installing Docker on RedHat/Fedora..."
sudo dnf install -y docker docker-compose
sudo systemctl enable docker
sudo systemctl start docker
;;
macos)
print_color $YELLOW "Please install Docker Desktop from https://www.docker.com/products/docker-desktop"
return 1
;;
*)
print_color $RED "Unsupported OS for automatic Docker installation"
return 1
;;
esac
# Add user to docker group
sudo usermod -aG docker $USER
print_color $GREEN "Docker installed. You may need to log out and back in for group changes to take effect."
}
# Install Go if not present
install_go() {
if command -v go >/dev/null 2>&1; then
print_color $GREEN "Go is already installed: $(go version)"
return 0
fi
print_color $BLUE "Installing Go..."
local os=$(detect_os)
local GO_VERSION="1.24.1"
local ARCH=$(uname -m)
# Map architecture
case $ARCH in
x86_64)
ARCH="amd64"
;;
aarch64|arm64)
ARCH="arm64"
;;
*)
print_color $RED "Unsupported architecture: $ARCH"
return 1
;;
esac
# Determine OS for Go download
local GO_OS=""
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
GO_OS="linux"
elif [[ "$OSTYPE" == "darwin"* ]]; then
GO_OS="darwin"
else
print_color $RED "Unsupported OS for Go installation"
return 1
fi
# Download and install Go
local GO_TAR="go${GO_VERSION}.${GO_OS}-${ARCH}.tar.gz"
wget "https://go.dev/dl/${GO_TAR}" -O /tmp/${GO_TAR}
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf /tmp/${GO_TAR}
rm /tmp/${GO_TAR}
# Add to PATH
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
echo 'export PATH=$PATH:$HOME/go/bin' >> ~/.bashrc
# For zsh users
if [ -f ~/.zshrc ]; then
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.zshrc
echo 'export PATH=$PATH:$HOME/go/bin' >> ~/.zshrc
fi
export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin
print_color $GREEN "Go ${GO_VERSION} installed successfully"
}
# Install dependencies
install_dependencies() {
local os=$1
print_color $BLUE "Installing dependencies for ${os}..."
case $os in
arch)
sudo pacman -Sy --noconfirm base-devel git jq make gcc
;;
debian)
sudo apt-get update
sudo apt-get install -y build-essential git jq make gcc
;;
redhat)
sudo dnf groupinstall -y "Development Tools"
sudo dnf install -y git jq make gcc
;;
macos)
# Check for Homebrew
if ! command -v brew >/dev/null 2>&1; then
print_color $YELLOW "Installing Homebrew..."
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
fi
brew install jq make gcc
;;
*)
print_color $YELLOW "Please manually install: git, jq, make, gcc"
;;
esac
}
# Setup function
setup_environment() {
local os=$(detect_os)
print_color $MAGENTA "=== Sonr Localnet Setup for ${os} ==="
# Install dependencies
install_dependencies $os
# Install Go
install_go
# Docker setup (optional)
print_color $BLUE "Would you like to install/configure Docker? (y/n)"
read -r response
if [[ "$response" =~ ^[Yy]$ ]]; then
if command -v docker >/dev/null 2>&1; then
print_color $GREEN "Docker is already installed"
# Check if user is in docker group
if ! groups | grep -q docker; then
print_color $YELLOW "Adding user to docker group..."
sudo usermod -aG docker $USER
print_color $YELLOW "You'll need to log out and back in for this to take effect"
fi
else
install_docker $os
fi
fi
# Build the binary
print_color $BLUE "Building Sonr binary..."
make install
# Create helpful aliases
print_color $BLUE "Creating helpful aliases..."
cat >> ~/.bashrc << 'EOF'
# Sonr aliases
alias sonr-localnet='cd $(pwd) && make localnet-x'
alias sonr-status='curl -s http://localhost:26657/status | jq'
alias sonr-logs='docker logs -f sonr-testnode 2>/dev/null || echo "No Docker container running"'
alias sonr-stop='docker stop sonr-testnode 2>/dev/null || pkill -f snrd'
EOF
if [ -f ~/.zshrc ]; then
cat >> ~/.zshrc << 'EOF'
# Sonr aliases
alias sonr-localnet='cd $(pwd) && make localnet-x'
alias sonr-status='curl -s http://localhost:26657/status | jq'
alias sonr-logs='docker logs -f sonr-testnode 2>/dev/null || echo "No Docker container running"'
alias sonr-stop='docker stop sonr-testnode 2>/dev/null || pkill -f snrd'
EOF
fi
print_color $GREEN "=== Setup Complete ==="
print_color $YELLOW "Next steps:"
print_color $YELLOW "1. If Docker was installed, log out and back in for group changes"
print_color $YELLOW "2. Run 'make localnet-x' to start the cross-platform localnet"
print_color $YELLOW "3. Or use the aliases: sonr-localnet, sonr-status, sonr-logs, sonr-stop"
# OS-specific instructions
case $os in
arch)
print_color $BLUE "\nArch Linux specific:"
print_color $YELLOW "- If you prefer systemd service:"
print_color $YELLOW " sudo cp etc/systemd/sonr.service /etc/systemd/system/sonr@${USER}.service"
print_color $YELLOW " sudo systemctl daemon-reload"
print_color $YELLOW " sudo systemctl enable sonr@${USER}"
print_color $YELLOW " sudo systemctl start sonr@${USER}"
;;
esac
}
# Main execution
main() {
# Check if we're in the right directory
if [ ! -f "Makefile" ] || [ ! -d "cmd/snrd" ]; then
print_color $RED "Error: This script must be run from the Sonr repository root"
exit 1
fi
setup_environment
}
# Run main
main "$@"
+351
View File
@@ -0,0 +1,351 @@
#!/bin/bash
# Starship E2E Testing Setup Script
# This script manages the Starship deployment for E2E testing
set -e
# Configuration
STARSHIP_VERSION="${STARSHIP_VERSION:-v2.0.0}"
STARSHIP_CONFIG="${STARSHIP_CONFIG:-chains/e2e-test.json}"
NAMESPACE="${NAMESPACE:-starship}"
TIMEOUT="${TIMEOUT:-300}"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Helper functions
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
# Check prerequisites
check_prerequisites() {
log_info "Checking prerequisites..."
# Check for kubectl
if ! command -v kubectl &> /dev/null; then
log_error "kubectl is required but not installed"
exit 1
fi
# Check for Docker
if ! command -v docker &> /dev/null; then
log_error "Docker is required but not installed"
exit 1
fi
# Check for Starship CLI
if ! command -v starship &> /dev/null; then
log_warning "Starship CLI not found, installing..."
install_starship
fi
log_info "Prerequisites check completed"
}
# Install Starship CLI
install_starship() {
log_info "Installing Starship CLI..."
npm install -g @starship-ci/cli@${STARSHIP_VERSION}
if ! command -v starship &> /dev/null; then
log_error "Failed to install Starship CLI"
exit 1
fi
log_info "Starship CLI installed successfully"
}
# Build Docker image
build_docker_image() {
log_info "Building Sonr Docker image..."
# Build the image
docker build -t sonr:local -f Dockerfile .
if [ $? -ne 0 ]; then
log_error "Failed to build Docker image"
exit 1
fi
log_info "Docker image built successfully"
}
# Start Starship network
start_network() {
log_info "Starting Starship network with config: ${STARSHIP_CONFIG}"
# Create namespace if it doesn't exist
kubectl create namespace ${NAMESPACE} --dry-run=client -o yaml | kubectl apply -f -
# Start Starship
starship start --config ${STARSHIP_CONFIG} --namespace ${NAMESPACE}
if [ $? -ne 0 ]; then
log_error "Failed to start Starship network"
exit 1
fi
log_info "Starship network started"
# Wait for network to be ready
wait_for_network
}
# Stop Starship network
stop_network() {
log_info "Stopping Starship network..."
starship stop --namespace ${NAMESPACE}
if [ $? -ne 0 ]; then
log_warning "Failed to stop Starship network gracefully"
fi
# Clean up namespace
kubectl delete namespace ${NAMESPACE} --ignore-not-found=true
log_info "Starship network stopped"
}
# Wait for network to be ready
wait_for_network() {
log_info "Waiting for network to be ready (timeout: ${TIMEOUT}s)..."
local start_time=$(date +%s)
local current_time
local elapsed
while true; do
current_time=$(date +%s)
elapsed=$((current_time - start_time))
if [ $elapsed -gt $TIMEOUT ]; then
log_error "Timeout waiting for network to be ready"
exit 1
fi
# Check if all pods are running
local ready_pods=$(kubectl get pods -n ${NAMESPACE} --no-headers | grep -c "Running\|Completed" || true)
local total_pods=$(kubectl get pods -n ${NAMESPACE} --no-headers | wc -l || true)
if [ "$ready_pods" -eq "$total_pods" ] && [ "$total_pods" -gt 0 ]; then
log_info "All pods are ready ($ready_pods/$total_pods)"
break
fi
log_info "Waiting for pods to be ready ($ready_pods/$total_pods)..."
sleep 5
done
# Additional wait for services to be fully initialized
log_info "Waiting for services to initialize..."
sleep 10
# Verify chain connectivity
verify_chain_connectivity
}
# Verify chain connectivity
verify_chain_connectivity() {
log_info "Verifying chain connectivity..."
# Port-forward to access the chains
kubectl port-forward -n ${NAMESPACE} service/sonr-1-validator 1317:1317 &
local pf_pid=$!
sleep 5
# Check if chain is responding
if curl -s http://localhost:1317/cosmos/base/tendermint/v1beta1/syncing | grep -q "syncing"; then
log_info "Chain 1 is responding"
else
log_error "Chain 1 is not responding"
kill $pf_pid 2>/dev/null
exit 1
fi
kill $pf_pid 2>/dev/null
# Check second chain
kubectl port-forward -n ${NAMESPACE} service/sonr-2-validator 1318:1318 &
pf_pid=$!
sleep 5
if curl -s http://localhost:1318/cosmos/base/tendermint/v1beta1/syncing | grep -q "syncing"; then
log_info "Chain 2 is responding"
else
log_error "Chain 2 is not responding"
kill $pf_pid 2>/dev/null
exit 1
fi
kill $pf_pid 2>/dev/null
log_info "Chain connectivity verified"
}
# Get network info
get_network_info() {
log_info "Network Information:"
echo "========================"
# Get pod status
echo "Pods:"
kubectl get pods -n ${NAMESPACE}
echo ""
# Get services
echo "Services:"
kubectl get services -n ${NAMESPACE}
echo ""
# Get endpoints
echo "Endpoints:"
echo "- Chain 1 REST: http://localhost:1317"
echo "- Chain 1 RPC: http://localhost:26657"
echo "- Chain 1 gRPC: localhost:9090"
echo "- Chain 2 REST: http://localhost:1318"
echo "- Chain 2 RPC: http://localhost:26658"
echo "- Chain 2 gRPC: localhost:9091"
echo "- Faucet: http://localhost:8000"
echo "- Registry: http://localhost:8081"
echo "- Explorer: http://localhost:8080"
echo "========================"
}
# Port forward for local access
setup_port_forward() {
log_info "Setting up port forwarding..."
# Chain 1
kubectl port-forward -n ${NAMESPACE} service/sonr-1-validator 1317:1317 26657:26657 9090:9090 &
# Chain 2
kubectl port-forward -n ${NAMESPACE} service/sonr-2-validator 1318:1318 26658:26658 9091:9091 &
# Faucet
kubectl port-forward -n ${NAMESPACE} service/faucet 8000:8000 &
# Registry
kubectl port-forward -n ${NAMESPACE} service/registry 8081:8081 &
# Explorer
kubectl port-forward -n ${NAMESPACE} service/explorer 8080:8080 &
log_info "Port forwarding established"
log_info "Press Ctrl+C to stop port forwarding and exit"
# Wait for interrupt
trap "kill 0" EXIT
wait
}
# Run E2E tests
run_e2e_tests() {
log_info "Running E2E tests..."
# Set up port forwarding in background
setup_port_forward &
local pf_pid=$!
# Wait for port forwarding to be established
sleep 5
# Run tests
cd test/e2e
if [ -n "$1" ]; then
# Run specific test
log_info "Running test: $1"
go test -v -race -run "$1" ./...
else
# Run all tests
log_info "Running all E2E tests"
go test -v -race ./...
fi
local test_result=$?
# Clean up port forwarding
kill $pf_pid 2>/dev/null
if [ $test_result -eq 0 ]; then
log_info "E2E tests passed successfully"
else
log_error "E2E tests failed"
exit 1
fi
}
# Main command handler
case "${1:-}" in
start)
check_prerequisites
build_docker_image
start_network
get_network_info
;;
stop)
stop_network
;;
restart)
stop_network
sleep 5
check_prerequisites
build_docker_image
start_network
get_network_info
;;
status)
get_network_info
;;
port-forward)
setup_port_forward
;;
test)
check_prerequisites
build_docker_image
start_network
run_e2e_tests "${2:-}"
stop_network
;;
test-only)
run_e2e_tests "${2:-}"
;;
*)
echo "Starship E2E Testing Manager"
echo ""
echo "Usage: $0 {start|stop|restart|status|port-forward|test|test-only} [test-name]"
echo ""
echo "Commands:"
echo " start - Start Starship network for E2E testing"
echo " stop - Stop Starship network"
echo " restart - Restart Starship network"
echo " status - Show network status and information"
echo " port-forward - Set up port forwarding for local access"
echo " test - Start network, run tests, then stop network"
echo " test-only - Run tests against existing network"
echo ""
echo "Examples:"
echo " $0 start # Start the network"
echo " $0 test # Run all E2E tests"
echo " $0 test TestBasicChain # Run specific test"
echo " $0 test-only TestIBC # Run test against existing network"
echo " $0 port-forward # Access network locally"
echo " $0 stop # Stop the network"
exit 1
;;
esac
Regular → Executable
+74 -74
View File
@@ -10,7 +10,7 @@ set -eu
export KEY="acc0"
export KEY2="acc1"
export CHAIN_ID=${CHAIN_ID:-"localchain-1"}
export CHAIN_ID=${CHAIN_ID:-"sonrtest_1-1"}
export MONIKER="localvalidator"
export KEYALGO="secp256k1"
export KEYRING=${KEYRING:-"test"}
@@ -34,119 +34,119 @@ app_toml="${HOME_DIR}/config/app.toml"
genesis_json="${HOME_DIR}/config/genesis.json"
# if which binary does not exist, install it
if [ -z $(which $BINARY) ]; then
make install
if [[ -z $(which "${BINARY}") ]]; then
make install
if [ -z $(which $BINARY) ]; then
echo "Ensure $BINARY is installed and in your PATH"
exit 1
fi
if [[ -z $(which "${BINARY}") ]]; then
echo "Ensure ${BINARY} is installed and in your PATH"
exit 1
fi
fi
command -v $BINARY >/dev/null 2>&1 || {
echo >&2 "$BINARY command not found. Ensure this is setup / properly installed in your GOPATH (make install)."
exit 1
command -v "${BINARY}" >/dev/null 2>&1 || {
echo >&2 "${BINARY} command not found. Ensure this is setup / properly installed in your GOPATH (make install)."
exit 1
}
command -v jq >/dev/null 2>&1 || {
echo >&2 "jq not installed. More info: https://stedolan.github.io/jq/download/"
exit 1
echo >&2 "jq not installed. More info: https://stedolan.github.io/jq/download/"
exit 1
}
set_config() {
$BINARY config set client chain-id $CHAIN_ID
$BINARY config set client keyring-backend $KEYRING
${BINARY} config set client chain-id "${CHAIN_ID}"
${BINARY} config set client keyring-backend "${KEYRING}"
}
set_config
from_scratch() {
# Fresh install on current branch
make install
# Fresh install on current branch
make install
# remove existing daemon files.
if [ ${#HOME_DIR} -le 2 ]; then
echo "HOME_DIR must be more than 2 characters long"
return
fi
rm -rf $HOME_DIR && echo "Removed $HOME_DIR"
# remove existing daemon files.
if [[ ${#HOME_DIR} -le 2 ]]; then
echo "HOME_DIR must be more than 2 characters long"
return
fi
rm -rf "${HOME_DIR}" && echo "Removed ${HOME_DIR}"
# reset values if not set already after whipe
set_config
# reset values if not set already after whipe
set_config
add_key() {
key=$1
mnemonic=$2
echo $mnemonic | $BINARY keys add $key --home $HOME_DIR --keyring-backend $KEYRING --algo $KEYALGO --recover
}
add_key() {
key=$1
mnemonic=$2
echo "${mnemonic}" | ${BINARY} keys add "${key}" --home "${HOME_DIR}" --keyring-backend "${KEYRING}" --algo "${KEYALGO}" --recover
}
# cosmos1efd63aw40lxf3n4mhf7dzhjkr453axur6cpk92
add_key $KEY "decorate bright ozone fork gallery riot bus exhaust worth way bone indoor calm squirrel merry zero scheme cotton until shop any excess stage laundry"
# cosmos1hj5fveer5cjtn4wd6wstzugjfdxzl0xpxvjjvr
add_key $KEY2 "wealth flavor believe regret funny network recall kiss grape useless pepper cram hint member few certain unveil rather brick bargain curious require crowd raise"
# cosmos1efd63aw40lxf3n4mhf7dzhjkr453axur6cpk92
add_key "${KEY}" "decorate bright ozone fork gallery riot bus exhaust worth way bone indoor calm squirrel merry zero scheme cotton until shop any excess stage laundry"
# cosmos1hj5fveer5cjtn4wd6wstzugjfdxzl0xpxvjjvr
add_key "${KEY2}" "wealth flavor believe regret funny network recall kiss grape useless pepper cram hint member few certain unveil rather brick bargain curious require crowd raise"
$BINARY init $CHAIN_ID --chain-id $CHAIN_ID --overwrite --default-denom $DENOM --home $HOME_DIR
${BINARY} init "${CHAIN_ID}" --chain-id "${CHAIN_ID}" --overwrite --default-denom "${DENOM}" --home "${HOME_DIR}"
update_test_genesis() {
cat $HOME_DIR/config/genesis.json | jq "$1" >$HOME_DIR/config/tmp_genesis.json && mv $HOME_DIR/config/tmp_genesis.json $HOME_DIR/config/genesis.json
}
update_test_genesis() {
cat "${HOME_DIR}"/config/genesis.json | jq "$1" >"${HOME_DIR}"/config/tmp_genesis.json && mv "${HOME_DIR}"/config/tmp_genesis.json "${HOME_DIR}"/config/genesis.json
}
# === CORE MODULES ===
# block
update_test_genesis '.consensus_params["block"]["max_gas"]="100000000"'
# crisis
update_test_genesis $(printf '.app_state["crisis"]["constant_fee"]={"denom":"%s","amount":"1000"}' $DENOM)
# === CORE MODULES ===
# block
update_test_genesis '.consensus_params["block"]["max_gas"]="100000000"'
# crisis
update_test_genesis $(printf '.app_state["crisis"]["constant_fee"]={"denom":"%s","amount":"1000"}' "${DENOM}")
# === CUSTOM MODULES ===
# tokenfactory
update_test_genesis '.app_state["tokenfactory"]["params"]["denom_creation_fee"]=[]'
update_test_genesis '.app_state["tokenfactory"]["params"]["denom_creation_gas_consume"]=100000'
# === CUSTOM MODULES ===
# tokenfactory
update_test_genesis '.app_state["tokenfactory"]["params"]["denom_creation_fee"]=[]'
update_test_genesis '.app_state["tokenfactory"]["params"]["denom_creation_gas_consume"]=100000'
$BINARY keys list --keyring-backend $KEYRING --home $HOME_DIR
${BINARY} keys list --keyring-backend "${KEYRING}" --home "${HOME_DIR}"
# Allocate genesis accounts
$BINARY genesis add-genesis-account $KEY 10000000$DENOM,900test --keyring-backend $KEYRING --home $HOME_DIR --append
$BINARY genesis add-genesis-account $KEY2 10000000$DENOM,800test --keyring-backend $KEYRING --home $HOME_DIR --append
# Allocate genesis accounts
${BINARY} genesis add-genesis-account "${KEY}" 10000000"${DENOM}",900test --keyring-backend "${KEYRING}" --home "${HOME_DIR}" --append
${BINARY} genesis add-genesis-account "${KEY2}" 10000000"${DENOM}",800test --keyring-backend "${KEYRING}" --home "${HOME_DIR}" --append
# ICS provider genesis hack
HACK_DIR=icshack-1 && echo $HACK_DIR
rm -rf $HACK_DIR
cp -r ${HOME_DIR} $HACK_DIR
# ICS provider genesis hack
HACK_DIR=icshack-1 && echo "${HACK_DIR}"
rm -rf "${HACK_DIR}"
cp -r "${HOME_DIR}" "${HACK_DIR}"
$BINARY add-consumer-section provider --home $HACK_DIR
ccvjson=$(jq '.app_state["ccvconsumer"]' $HACK_DIR/config/genesis.json)
echo $ccvjson
jq '.app_state["ccvconsumer"] = '"$ccvjson" ${HACK_DIR}/config/genesis.json >json.tmp && mv json.tmp $genesis_json
rm -rf $HACK_DIR
${BINARY} add-consumer-section provider --home "${HACK_DIR}"
ccvjson=$(jq '.app_state["ccvconsumer"]' "${HACK_DIR}"/config/genesis.json)
echo "${ccvjson}"
jq '.app_state["ccvconsumer"] = '"${ccvjson}" "${HACK_DIR}"/config/genesis.json >json.tmp && mv json.tmp "${genesis_json}"
rm -rf "${HACK_DIR}"
update_test_genesis $(printf '.app_state["ccvconsumer"]["params"]["unbonding_period"]="%s"' "240s")
update_test_genesis $(printf '.app_state["ccvconsumer"]["params"]["unbonding_period"]="%s"' "240s")
}
# check if CLEAN is not set to false
if [ "$CLEAN" != "false" ]; then
echo "Starting from a clean state"
from_scratch
if [[ ${CLEAN} != "false" ]]; then
echo "Starting from a clean state"
from_scratch
fi
# Opens the RPC endpoint to outside connections
sed -i -e 's/laddr = "tcp:\/\/127.0.0.1:26657"/c\laddr = "tcp:\/\/0.0.0.0:'$RPC'"/g' $HOME_DIR/config/config.toml
sed -i -e 's/cors_allowed_origins = \[\]/cors_allowed_origins = \["\*"\]/g' $HOME_DIR/config/config.toml
sed -i -e 's/laddr = "tcp:\/\/127.0.0.1:26657"/c\laddr = "tcp:\/\/0.0.0.0:'"${RPC}"'"/g' "${HOME_DIR}"/config/config.toml
sed -i -e 's/cors_allowed_origins = \[\]/cors_allowed_origins = \["\*"\]/g' "${HOME_DIR}"/config/config.toml
# REST endpoint
sed -i -e 's/address = "tcp:\/\/localhost:1317"/address = "tcp:\/\/0.0.0.0:'$REST'"/g' $HOME_DIR/config/app.toml
sed -i -e 's/enable = false/enable = true/g' $HOME_DIR/config/app.toml
sed -i -e 's/address = "tcp:\/\/localhost:1317"/address = "tcp:\/\/0.0.0.0:'"${REST}"'"/g' "${HOME_DIR}"/config/app.toml
sed -i -e 's/enable = false/enable = true/g' "${HOME_DIR}"/config/app.toml
# peer exchange
sed -i -e 's/pprof_laddr = "localhost:6060"/pprof_laddr = "localhost:'$PROFF'"/g' $HOME_DIR/config/config.toml
sed -i -e 's/laddr = "tcp:\/\/0.0.0.0:26656"/laddr = "tcp:\/\/0.0.0.0:'$P2P'"/g' $HOME_DIR/config/config.toml
sed -i -e 's/pprof_laddr = "localhost:6060"/pprof_laddr = "localhost:'"${PROFF}"'"/g' "${HOME_DIR}"/config/config.toml
sed -i -e 's/laddr = "tcp:\/\/0.0.0.0:26656"/laddr = "tcp:\/\/0.0.0.0:'"${P2P}"'"/g' "${HOME_DIR}"/config/config.toml
# GRPC
sed -i -e 's/address = "localhost:9090"/address = "0.0.0.0:'$GRPC'"/g' $HOME_DIR/config/app.toml
sed -i -e 's/address = "localhost:9091"/address = "0.0.0.0:'$GRPC_WEB'"/g' $HOME_DIR/config/app.toml
sed -i -e 's/address = "localhost:9090"/address = "0.0.0.0:'"${GRPC}"'"/g' "${HOME_DIR}"/config/app.toml
sed -i -e 's/address = "localhost:9091"/address = "0.0.0.0:'"${GRPC_WEB}"'"/g' "${HOME_DIR}"/config/app.toml
# Rosetta Api
sed -i -e 's/address = ":8080"/address = "0.0.0.0:'$ROSETTA'"/g' $HOME_DIR/config/app.toml
sed -i -e 's/address = ":8080"/address = "0.0.0.0:'"${ROSETTA}"'"/g' "${HOME_DIR}"/config/app.toml
# Faster blocks
sed -i -e 's/timeout_commit = "5s"/timeout_commit = "'$BLOCK_TIME'"/g' $HOME_DIR/config/config.toml
sed -i -e 's/timeout_commit = "5s"/timeout_commit = "'"${BLOCK_TIME}"'"/g' "${HOME_DIR}"/config/config.toml
# Start the daemon in the background
$BINARY start --pruning=nothing --minimum-gas-prices=0$DENOM --rpc.laddr="tcp://0.0.0.0:$RPC" --home $HOME_DIR
${BINARY} start --pruning=nothing --minimum-gas-prices=0"${DENOM}" --rpc.laddr="tcp://0.0.0.0:${RPC}" --home "${HOME_DIR}"
Regular → Executable
+355 -102
View File
@@ -2,25 +2,23 @@
# Run this script to quickly install, setup, and run the current version of the network without docker.
#
# Examples:
# CHAIN_ID="local-1" HOME_DIR="~/.core" BLOCK_TIME="1000ms" CLEAN=true sh scripts/test_node.sh
# CHAIN_ID="local-2" HOME_DIR="~/.core" CLEAN=true RPC=36657 REST=2317 PROFF=6061 P2P=36656 GRPC=8090 GRPC_WEB=8091 ROSETTA=8081 BLOCK_TIME="500ms" sh scripts/test_node.sh
# CHAIN_ID="localchain_9000-1" HOME_DIR="~/.sonr" BLOCK_TIME="1000ms" CLEAN=true sh scripts/test_node.sh
# CHAIN_ID="localchain_9000-2" HOME_DIR="~/.sonr" CLEAN=true RPC=36657 REST=2317 PROFF=6061 P2P=36656 GRPC=8090 GRPC_WEB=8091 ROSETTA=8081 BLOCK_TIME="500ms" sh scripts/test_node.sh
export KEY0_NAME=${KEY0_NAME:-"user0"}
export KEY0_MNEMONIC=${KEY0_MNEMONIC:-"decorate bright ozone fork gallery riot bus exhaust worth way bone indoor calm squirrel merry zero scheme cotton until shop any excess stage laundry"}
export KEY1_NAME="user2"
export KEY1_MNEMONIC=${KEY1_MNEMONIC:-"wealth flavor believe regret funny network recall kiss grape useless pepper cram hint member few certain unveil rather brick bargain curious require crowd raise"}
set -eu
export TX_INDEX_INDEXER=${TX_INDEX_INDEXER:-"kv"}
export TX_INDEX_PSQL_CONN=${TX_INDEX_PSQL_CONN:-""}
export CHAIN_ID=${CHAIN_ID:-"sonr-testnet-1"}
export MONIKER="florence"
export KEYALGO="secp256k1"
export KEY="acc0"
export KEY2="acc1"
export CHAIN_ID=${CHAIN_ID:-"sonrtest_1-1"}
export MONIKER="localvalidator"
export KEYALGO="eth_secp256k1"
export KEYRING=${KEYRING:-"test"}
export HOME_DIR=$(eval echo "${HOME_DIR:-"~/.sonr"}")
export BINARY=${BINARY:-sonrd}
export BINARY=${BINARY:-snrd}
export DENOM=${DENOM:-usnr}
export CLEAN=${CLEAN:-"true"}
export CLEAN=${CLEAN:-"false"}
export RPC=${RPC:-"26657"}
export REST=${REST:-"1317"}
export PROFF=${PROFF:-"6060"}
@@ -28,138 +26,393 @@ export P2P=${P2P:-"26656"}
export GRPC=${GRPC:-"9090"}
export GRPC_WEB=${GRPC_WEB:-"9091"}
export ROSETTA=${ROSETTA:-"8080"}
export JSON_RPC=${JSON_RPC:-"8545"}
export JSON_RPC_WS=${JSON_RPC_WS:-"8546"}
export BLOCK_TIME=${BLOCK_TIME:-"5s"}
ROOT_DIR=$(git rev-parse --show-toplevel)
# Configurable Mnemomics
export SONR_MNEMONIC_1=${SONR_MNEMONIC_1:-"decorate bright ozone fork gallery riot bus exhaust worth way bone indoor calm squirrel merry zero scheme cotton until shop any excess stage laundry"}
export SONR_MNEMONIC_2=${SONR_MNEMONIC_2:-"wealth flavor believe regret funny network recall kiss grape useless pepper cram hint member few certain unveil rather brick bargain curious require crowd raise"}
# if which binary does not exist, exit
if [ -z `which $BINARY` ]; then
echo "Ensure $BINARY is installed and in your PATH"
exit 1
# Check if binary exists, if not use Docker (or force Docker if requested)
export FORCE_DOCKER=${FORCE_DOCKER:-"false"}
export SKIP_INSTALL=${SKIP_INSTALL:-"false"}
USE_DOCKER=false
if [[ "${FORCE_DOCKER}" == "true" ]] || [[ -z $(which "${BINARY}") ]]; then
# Check if Docker is available and use it
if command -v docker >/dev/null 2>&1; then
if [[ "${FORCE_DOCKER}" == "true" ]]; then
echo "Force Docker mode enabled, using Docker image onsonr/snrd:latest..."
else
echo "Binary ${BINARY} not found locally, checking for Docker image onsonr/snrd:latest..."
fi
if docker image inspect onsonr/snrd:latest >/dev/null 2>&1; then
echo "Using Docker image onsonr/snrd:latest"
USE_DOCKER=true
else
echo "Docker image onsonr/snrd:latest not found. Pulling image..."
docker pull onsonr/snrd:latest || {
echo "Failed to pull onsonr/snrd:latest. Please ensure Docker is running and you have internet access."
exit 1
}
USE_DOCKER=true
fi
else
echo "Binary ${BINARY} not found. Please either:"
echo " 1. Install ${BINARY} with 'make install'"
echo " 2. Install Docker to use the containerized version"
exit 1
fi
fi
alias BINARY="$BINARY --home=$HOME_DIR"
# Final check if not using Docker
if [[ "${USE_DOCKER}" == "false" ]]; then
command -v "${BINARY}" >/dev/null 2>&1 || {
echo >&2 "${BINARY} command not found. Ensure this is setup / properly installed in your GOPATH (make install)."
exit 1
}
fi
command -v jq >/dev/null 2>&1 || {
echo >&2 "jq not installed. More info: https://stedolan.github.io/jq/download/"
exit 1
}
command -v $BINARY > /dev/null 2>&1 || { echo >&2 "$BINARY command not found. Ensure this is setup / properly installed in your GOPATH (make install)."; exit 1; }
command -v jq > /dev/null 2>&1 || { echo >&2 "jq not installed. More info: https://stedolan.github.io/jq/download/"; exit 1; }
# generate_vrf_key generates a VRF keypair and stores it securely
# Mirrors the Go implementation in app/commands/enhance_init.go
generate_vrf_key() {
local home_dir="$1"
local use_docker="${2:-false}"
# Validate parameters
if [[ -z "${home_dir}" ]]; then
echo "Error: HOME_DIR parameter is required" >&2
return 1
fi
# Path to genesis file
local genesis_file="${home_dir}/config/genesis.json"
# Check if genesis file exists
if [[ ! -f "${genesis_file}" ]]; then
echo "Error: Genesis file not found at ${genesis_file}" >&2
return 1
fi
# Extract chain-id from genesis file
local chain_id
chain_id=$(jq -r '.chain_id' "${genesis_file}" 2>/dev/null)
if [[ -z "${chain_id}" || "${chain_id}" == "null" ]]; then
echo "Error: Failed to extract chain-id from genesis file" >&2
return 1
fi
echo "Generating VRF keypair for network: ${chain_id}"
# Create deterministic entropy from chain-id using SHA256
local entropy_seed
entropy_seed=$(echo -n "${chain_id}" | sha256sum | cut -d' ' -f1)
# Generate 64 bytes of deterministic randomness
local seed_part1="${entropy_seed}"
local seed_part2
seed_part2=$(echo -n "${entropy_seed}" | sha256sum | cut -d' ' -f1)
# Combine to create 64 bytes of hex data
local vrf_key_hex="${seed_part1}${seed_part2}"
# Ensure we have exactly 128 hex characters (64 bytes)
if [[ ${#vrf_key_hex} -ne 128 ]]; then
echo "Error: Generated VRF key has incorrect size: ${#vrf_key_hex}" >&2
return 1
fi
# Path to store VRF secret key
local vrf_key_path="${home_dir}/vrf_secret.key"
# Ensure directory exists
mkdir -p "${home_dir}"
# Convert hex to binary and write to file
echo -n "${vrf_key_hex}" | xxd -r -p > "${vrf_key_path}"
# Set restrictive permissions (owner read/write only)
chmod 0600 "${vrf_key_path}"
# Validate file was created with correct size (64 bytes)
local file_size
file_size=$(wc -c < "${vrf_key_path}")
if [[ ${file_size} -ne 64 ]]; then
echo "Error: VRF key file has incorrect size: ${file_size} bytes" >&2
rm -f "${vrf_key_path}"
return 1
fi
echo "✓ VRF keypair generated for network: ${chain_id}"
echo "✓ VRF secret key stored securely: ${vrf_key_path}"
return 0
}
# Create wrapper function for binary execution
run_binary() {
if [[ "${USE_DOCKER}" == "true" ]]; then
# Ensure the directory exists on the host
mkdir -p "${HOME_DIR}"
# Determine if we're in a TTY
DOCKER_TTY_FLAG=""
if [ -t 0 ]; then
DOCKER_TTY_FLAG="-it"
fi
# Mount home directory to container's /root/.sonr
docker run --rm ${DOCKER_TTY_FLAG} \
-v "${HOME_DIR}:/root/.sonr" \
--network host \
onsonr/snrd:latest \
snrd --home /root/.sonr "$@"
else
${BINARY} "$@"
fi
}
set_config() {
$BINARY config set client chain-id $CHAIN_ID
$BINARY config set client keyring-backend $KEYRING
run_binary config set client chain-id "${CHAIN_ID}"
run_binary config set client keyring-backend "${KEYRING}"
}
set_config
from_scratch () {
# Fresh install on current branch
make install
from_scratch() {
# Fresh install on current branch (skip if using Docker or SKIP_INSTALL is true)
if [[ "${USE_DOCKER}" == "false" ]] && [[ "${SKIP_INSTALL}" == "false" ]]; then
make install
fi
# remove existing daemon files.
if [ ${#HOME_DIR} -le 2 ]; then
echo "HOME_DIR must be more than 2 characters long"
return
fi
rm -rf $HOME_DIR && echo "Removed $HOME_DIR"
# remove existing daemon files.
if [[ ${#HOME_DIR} -le 2 ]]; then
echo "HOME_DIR must be more than 2 characters long"
return
fi
rm -rf "${HOME_DIR}" && echo "Removed ${HOME_DIR}"
# reset values if not set already after whipe
set_config
# reset values if not set already after whipe
set_config
add_key() {
echo "Adding key: $1"
key=$1
mnemonic=$2
}
add_key() {
key=$1
mnemonic=$2
if [[ "${USE_DOCKER}" == "true" ]]; then
# For Docker, we need to pass the mnemonic differently
mkdir -p "${HOME_DIR}"
echo "${mnemonic}" | docker run --rm -i \
-v "${HOME_DIR}:/root/.sonr" \
--network host \
onsonr/snrd:latest \
snrd --home /root/.sonr keys add "${key}" --keyring-backend "${KEYRING}" --algo "${KEYALGO}" --recover
else
echo "${mnemonic}" | ${BINARY} keys add "${key}" --keyring-backend "${KEYRING}" --algo "${KEYALGO}" --home "${HOME_DIR}" --recover
fi
}
# idx1efd63aw40lxf3n4mhf7dzhjkr453axur9vjt6y
echo "$KEY0_MNEMONIC" | BINARY keys add $KEY0_NAME --keyring-backend $KEYRING --algo $KEYALGO --recover
echo "$KEY1_MNEMONIC" | BINARY keys add $KEY1_NAME --keyring-backend $KEYRING --algo $KEYALGO --recover
# idx140fehngcrxvhdt84x729p3f0qmkmea8n570lrg
add_key "${KEY}" "${SONR_MNEMONIC_1}"
# chain initial setup
BINARY init $MONIKER --chain-id $CHAIN_ID --default-denom $DENOM
# idx1r6yue0vuyj9m7xw78npspt9drq2tmtvgcrf7sr
add_key "${KEY2}" "${SONR_MNEMONIC_2}"
update_test_genesis () {
cat $HOME_DIR/config/genesis.json | jq "$1" > $HOME_DIR/config/tmp_genesis.json && mv $HOME_DIR/config/tmp_genesis.json $HOME_DIR/config/genesis.json
}
if [[ "${USE_DOCKER}" == "true" ]]; then
# For Docker init, we need to handle it specially
docker run --rm \
-v "${HOME_DIR}:/root/.sonr" \
--network host \
onsonr/snrd:latest \
snrd --home /root/.sonr init "${MONIKER}" --chain-id "${CHAIN_ID}" --default-denom "${DENOM}"
else
${BINARY} init "${MONIKER}" --chain-id "${CHAIN_ID}" --default-denom "${DENOM}" --home "${HOME_DIR}"
fi
# === CORE MODULES ===
update_test_genesis() {
cat "${HOME_DIR}"/config/genesis.json | jq "$1" >"${HOME_DIR}"/config/tmp_genesis.json && mv "${HOME_DIR}"/config/tmp_genesis.json "${HOME_DIR}"/config/genesis.json
}
# Block
update_test_genesis '.consensus_params["block"]["max_gas"]="100000000"'
# === CORE MODULES ===
# Gov
update_test_genesis `printf '.app_state["gov"]["params"]["min_deposit"]=[{"denom":"%s","amount":"1000000"}]' $DENOM`
update_test_genesis '.app_state["gov"]["params"]["voting_period"]="30s"'
update_test_genesis '.app_state["gov"]["params"]["expedited_voting_period"]="15s"'
# Block
update_test_genesis '.consensus_params["block"]["max_gas"]="100000000"'
# staking
update_test_genesis `printf '.app_state["staking"]["params"]["bond_denom"]="%s"' $DENOM`
update_test_genesis '.app_state["staking"]["params"]["min_commission_rate"]="0.050000000000000000"'
# Gov
update_test_genesis $(printf '.app_state["gov"]["params"]["min_deposit"]=[{"denom":"%s","amount":"1000000"}]' "${DENOM}")
update_test_genesis '.app_state["gov"]["params"]["voting_period"]="30s"'
update_test_genesis '.app_state["gov"]["params"]["expedited_voting_period"]="15s"'
# mint
update_test_genesis `printf '.app_state["mint"]["params"]["mint_denom"]="%s"' $DENOM`
# Add CONSTITUTION.md to governance if it exists
if [ -f "CONSTITUTION.md" ]; then
CONSTITUTION_CONTENT=$(cat CONSTITUTION.md | jq -Rs .)
update_test_genesis ".app_state[\"gov\"][\"constitution\"]=$CONSTITUTION_CONTENT"
fi
# crisis
update_test_genesis `printf '.app_state["crisis"]["constant_fee"]={"denom":"%s","amount":"1000"}' $DENOM`
update_test_genesis $(printf '.app_state["evm"]["params"]["evm_denom"]="%s"' "${DENOM}")
update_test_genesis '.app_state["evm"]["params"]["active_static_precompiles"]=["0x0000000000000000000000000000000000000100","0x0000000000000000000000000000000000000400","0x0000000000000000000000000000000000000800","0x0000000000000000000000000000000000000801","0x0000000000000000000000000000000000000802","0x0000000000000000000000000000000000000803","0x0000000000000000000000000000000000000804","0x0000000000000000000000000000000000000805"]'
update_test_genesis '.app_state["erc20"]["params"]["native_precompiles"]=["0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"]' # https://eips.ethereum.org/EIPS/eip-7528
update_test_genesis $(printf '.app_state["erc20"]["token_pairs"]=[{contract_owner:1,erc20_address:"0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",denom:"%s",enabled:true}]' "${DENOM}")
update_test_genesis '.app_state["feemarket"]["params"]["no_base_fee"]=true'
update_test_genesis '.app_state["feemarket"]["params"]["base_fee"]="0.000000000000000000"'
# === CUSTOM MODULES ===
# globalfee
update_test_genesis `printf '.app_state["globalfee"]["params"]["minimum_gas_prices"]=[{"amount":"0.000000000000000000","denom":"%s"}]' $DENOM`
# tokenfactory
update_test_genesis '.app_state["tokenfactory"]["params"]["denom_creation_fee"]=[]'
update_test_genesis '.app_state["tokenfactory"]["params"]["denom_creation_gas_consume"]=100000'
# poa
update_test_genesis '.app_state["poa"]["params"]["admins"]=["idx10d07y265gmmuvt4z0w9aw880jnsr700j9kqcfa"]'
# staking
update_test_genesis $(printf '.app_state["staking"]["params"]["bond_denom"]="%s"' "${DENOM}")
update_test_genesis '.app_state["staking"]["params"]["min_commission_rate"]="0.050000000000000000"'
# Allocate genesis accounts
BINARY genesis add-genesis-account $KEY0_NAME 10000000$DENOM,900snr --keyring-backend $KEYRING
BINARY genesis add-genesis-account $KEY1_NAME 10000000$DENOM,800snr --keyring-backend $KEYRING
# mint
update_test_genesis $(printf '.app_state["mint"]["params"]["mint_denom"]="%s"' "${DENOM}")
# Sign genesis transaction
BINARY genesis gentx $KEY0_NAME 1000000$DENOM --keyring-backend $KEYRING --chain-id $CHAIN_ID
# crisis
update_test_genesis $(printf '.app_state["crisis"]["constant_fee"]={"denom":"%s","amount":"1000"}' "${DENOM}")
BINARY genesis collect-gentxs
## abci
update_test_genesis '.consensus["params"]["abci"]["vote_extensions_enable_height"]="1"'
BINARY genesis validate-genesis
err=$?
if [ $err -ne 0 ]; then
echo "Failed to validate genesis"
return
fi
# === CUSTOM MODULES ===
# tokenfactory
update_test_genesis '.app_state["tokenfactory"]["params"]["denom_creation_fee"]=[]'
update_test_genesis '.app_state["tokenfactory"]["params"]["denom_creation_gas_consume"]=100000'
BASE_GENESIS_ALLOCATIONS="100000000000000000000000000${DENOM},100000000test"
# Allocate genesis accounts
if [[ "${USE_DOCKER}" == "true" ]]; then
docker run --rm \
-v "${HOME_DIR}:/root/.sonr" \
--network host \
onsonr/snrd:latest \
snrd --home /root/.sonr genesis add-genesis-account "${KEY}" "${BASE_GENESIS_ALLOCATIONS}" --keyring-backend "${KEYRING}" --append
docker run --rm \
-v "${HOME_DIR}:/root/.sonr" \
--network host \
onsonr/snrd:latest \
snrd --home /root/.sonr genesis add-genesis-account "${KEY2}" "${BASE_GENESIS_ALLOCATIONS}" --keyring-backend "${KEYRING}" --append
# Sign genesis transaction
docker run --rm \
-v "${HOME_DIR}:/root/.sonr" \
--network host \
onsonr/snrd:latest \
snrd --home /root/.sonr genesis gentx "${KEY}" 1000000000000000000000"${DENOM}" --gas-prices 0"${DENOM}" --keyring-backend "${KEYRING}" --chain-id "${CHAIN_ID}"
docker run --rm \
-v "${HOME_DIR}:/root/.sonr" \
--network host \
onsonr/snrd:latest \
snrd --home /root/.sonr genesis collect-gentxs
docker run --rm \
-v "${HOME_DIR}:/root/.sonr" \
--network host \
onsonr/snrd:latest \
snrd --home /root/.sonr genesis validate-genesis
else
${BINARY} genesis add-genesis-account "${KEY}" "${BASE_GENESIS_ALLOCATIONS}" --keyring-backend "${KEYRING}" --home "${HOME_DIR}" --append
${BINARY} genesis add-genesis-account "${KEY2}" "${BASE_GENESIS_ALLOCATIONS}" --keyring-backend "${KEYRING}" --home "${HOME_DIR}" --append
# Sign genesis transaction
${BINARY} genesis gentx "${KEY}" 1000000000000000000000"${DENOM}" --gas-prices 0"${DENOM}" --keyring-backend "${KEYRING}" --chain-id "${CHAIN_ID}" --home "${HOME_DIR}"
${BINARY} genesis collect-gentxs --home "${HOME_DIR}"
${BINARY} genesis validate-genesis --home "${HOME_DIR}"
fi
err=$?
if [[ ${err} -ne 0 ]]; then
echo "Failed to validate genesis"
return
fi
}
# check if CLEAN is not set to false
if [ "$CLEAN" != "false" ]; then
echo "Starting from a clean state"
from_scratch
if [[ ${CLEAN} != "false" ]]; then
echo "Starting from a clean state"
from_scratch
# Generate VRF keypair (must be done after genesis file is created)
echo ""
echo "Generating VRF keypair..."
if ! generate_vrf_key "${HOME_DIR}" "${USE_DOCKER}"; then
echo "Warning: VRF key generation failed, but continuing..."
echo "Note: Multi-validator encryption features may not work without VRF keys"
fi
fi
echo "Starting node..."
# Tx Index
if [ "$TX_INDEX_PSQL_CONN" != "" ]; then
awk -v conn="$TX_INDEX_PSQL_CONN" '/^psql-conn = / {$0 = "psql-conn = \"" conn "\""} 1' $HOME_DIR/config/config.toml > temp && mv temp $HOME_DIR/config/config.toml
fi
# Opens the RPC endpoint to outside connections
sed -i 's/laddr = "tcp:\/\/127.0.0.1:26657"/c\laddr = "tcp:\/\/0.0.0.0:'$RPC'"/g' $HOME_DIR/config/config.toml
sed -i 's/cors_allowed_origins = \[\]/cors_allowed_origins = \["\*"\]/g' $HOME_DIR/config/config.toml
sed -i -e 's/laddr = "tcp:\/\/127.0.0.1:26657"/laddr = "tcp:\/\/0.0.0.0:'"${RPC}"'"/g' "${HOME_DIR}"/config/config.toml
sed -i -e 's/cors_allowed_origins = \[\]/cors_allowed_origins = \["*"\]/g' "${HOME_DIR}"/config/config.toml
# REST endpoint
sed -i 's/address = "tcp:\/\/localhost:1317"/address = "tcp:\/\/0.0.0.0:'$REST'"/g' $HOME_DIR/config/app.toml
sed -i 's/enable = false/enable = true/g' $HOME_DIR/config/app.toml
sed -i -e 's/address = "tcp:\/\/localhost:1317"/address = "tcp:\/\/0.0.0.0:'"${REST}"'"/g' "${HOME_DIR}"/config/app.toml
sed -i -e 's/enable = false/enable = true/g' "${HOME_DIR}"/config/app.toml
sed -i -e 's/enabled-unsafe-cors = false/enabled-unsafe-cors = true/g' "${HOME_DIR}"/config/app.toml
# peer exchange
sed -i 's/pprof_laddr = "localhost:6060"/pprof_laddr = "localhost:'$PROFF_LADDER'"/g' $HOME_DIR/config/config.toml
sed -i 's/laddr = "tcp:\/\/0.0.0.0:26656"/laddr = "tcp:\/\/0.0.0.0:'$P2P'"/g' $HOME_DIR/config/config.toml
sed -i -e 's/pprof_laddr = "localhost:6060"/pprof_laddr = "localhost:'"${PROFF}"'"/g' "${HOME_DIR}"/config/config.toml
sed -i -e 's/laddr = "tcp:\/\/0.0.0.0:26656"/laddr = "tcp:\/\/0.0.0.0:'"${P2P}"'"/g' "${HOME_DIR}"/config/config.toml
# GRPC
sed -i 's/address = "localhost:9090"/address = "0.0.0.0:'$GRPC'"/g' $HOME_DIR/config/app.toml
sed -i 's/address = "localhost:9091"/address = "0.0.0.0:'$GRPC_WEB'"/g' $HOME_DIR/config/app.toml
sed -i -e 's/address = "localhost:9090"/address = "0.0.0.0:'"${GRPC}"'"/g' "${HOME_DIR}"/config/app.toml
sed -i -e 's/address = "localhost:9091"/address = "0.0.0.0:'"${GRPC_WEB}"'"/g' "${HOME_DIR}"/config/app.toml
# Rosetta Api
sed -i 's/address = ":8080"/address = "0.0.0.0:'$ROSETTA'"/g' $HOME_DIR/config/app.toml
sed -i 's/indexer = "kv"/indexer = "'$TX_INDEX_INDEXER'"/g' $HOME_DIR/config/config.toml
sed -i -e 's/address = ":8080"/address = "0.0.0.0:'"${ROSETTA}"'"/g' "${HOME_DIR}"/config/app.toml
# JSON-RPC
sed -i -e '/\[json-rpc\]/,/^\[/ s/enable = false/enable = true/' "${HOME_DIR}"/config/app.toml
sed -i -e '/\[json-rpc\]/,/^\[/ s/address = "127.0.0.1:8545"/address = "0.0.0.0:'"${JSON_RPC}"'"/' "${HOME_DIR}"/config/app.toml
sed -i -e '/\[json-rpc\]/,/^\[/ s/ws-address = "127.0.0.1:8546"/ws-address = "0.0.0.0:'"${JSON_RPC_WS}"'"/' "${HOME_DIR}"/config/app.toml
# Start the node with 0 gas fees
BINARY start --pruning=nothing --minimum-gas-prices=0$DENOM --rpc.laddr="tcp://0.0.0.0:$RPC" --grpc.address="0.0.0.0:$GRPC" --grpc-web.enable=true
# Faster blocks
sed -i -e 's/timeout_commit = "5s"/timeout_commit = "'"${BLOCK_TIME}"'"/g' "${HOME_DIR}"/config/config.toml
# Start the node (with or without Docker)
if [[ "${USE_DOCKER}" == "true" ]]; then
echo "Starting node using Docker..."
# Check for detached mode via environment variable or prompt
DETACHED_MODE=""
if [[ "${DOCKER_DETACHED}" == "true" ]]; then
DETACHED_MODE="-d"
echo "Running in detached mode. Use 'docker logs -f sonr-testnode' to view logs."
echo "Stop with: docker stop sonr-testnode"
elif [ -t 0 ]; then
echo ""
echo "Would you like to run the node in detached mode (background)? [y/N]"
read -r -n 1 DETACH_RESPONSE
echo ""
if [[ "$DETACH_RESPONSE" =~ ^[Yy]$ ]]; then
DETACHED_MODE="-d"
echo "Running in detached mode. Use 'docker logs -f sonr-testnode' to view logs."
echo "Stop with: docker stop sonr-testnode"
else
echo "Running in foreground mode. Use Ctrl+C to stop."
fi
fi
# Determine if we're in a TTY (only for non-detached mode)
DOCKER_TTY_FLAG=""
if [ -t 0 ] && [ -z "$DETACHED_MODE" ]; then
DOCKER_TTY_FLAG="-it"
fi
docker run --rm ${DETACHED_MODE} ${DOCKER_TTY_FLAG} \
-v "${HOME_DIR}:/root/.sonr" \
--network host \
--name sonr-testnode \
onsonr/snrd:latest \
snrd start --pruning=nothing --minimum-gas-prices=0"${DENOM}" --rpc.laddr="tcp://0.0.0.0:${RPC}" --home /root/.sonr --json-rpc.api=eth,txpool,personal,net,debug,web3 --json-rpc.address="0.0.0.0:${JSON_RPC}" --json-rpc.ws-address="0.0.0.0:${JSON_RPC_WS}" --chain-id="${CHAIN_ID}"
# If running detached, show status
if [ -n "$DETACHED_MODE" ]; then
echo ""
echo "✅ Node started in background"
echo ""
echo "Useful commands:"
echo " View logs: docker logs -f sonr-testnode"
echo " Stop node: docker stop sonr-testnode"
echo " Node status: curl http://localhost:${RPC}/status | jq '.result.sync_info'"
echo ""
fi
else
${BINARY} start --pruning=nothing --minimum-gas-prices=0"${DENOM}" --rpc.laddr="tcp://0.0.0.0:${RPC}" --home "${HOME_DIR}" --json-rpc.api=eth,txpool,personal,net,debug,web3 --json-rpc.address="0.0.0.0:${JSON_RPC}" --json-rpc.ws-address="0.0.0.0:${JSON_RPC_WS}" --chain-id="${CHAIN_ID}"
fi
+130
View File
@@ -0,0 +1,130 @@
#!/bin/bash
DENOM="${DENOM:=usnr}"
CHAIN_BIN="${CHAIN_BIN:=snrd}"
CHAIN_DIR="${CHAIN_DIR:=$HOME/.sonr}"
set -eux
ls "$CHAIN_DIR"/config
echo "Update genesis.json file with updated local params"
sed -i -e "s/\"stake\"/\"$DENOM\"/g" "$CHAIN_DIR"/config/genesis.json
sed -i "s/\"time_iota_ms\": \".*\"/\"time_iota_ms\": \"$TIME_IOTA_MS\"/" "$CHAIN_DIR"/config/genesis.json
echo "Update max gas param"
jq -r '.consensus.params.block.max_gas |= "100000000000"' "$CHAIN_DIR"/config/genesis.json >/tmp/genesis.json
mv /tmp/genesis.json "$CHAIN_DIR"/config/genesis.json
echo "Update staking unbonding time and slashing jail time"
jq -r '.app_state.staking.params.unbonding_time |= "300s"' "$CHAIN_DIR"/config/genesis.json >/tmp/genesis.json
mv /tmp/genesis.json "$CHAIN_DIR"/config/genesis.json
jq -r '.app_state.slashing.params.downtime_jail_duration |= "60s"' "$CHAIN_DIR"/config/genesis.json >/tmp/genesis.json
mv /tmp/genesis.json "$CHAIN_DIR"/config/genesis.json
# overrides for older sdk versions, before 0.47
function gov_overrides_sdk_v46() {
jq -r '.app_state.gov.deposit_params.max_deposit_period |= "30s"' "$CHAIN_DIR"/config/genesis.json >/tmp/genesis.json
mv /tmp/genesis.json "$CHAIN_DIR"/config/genesis.json
jq -r '.app_state.gov.deposit_params.min_deposit[0].amount |= "10"' "$CHAIN_DIR"/config/genesis.json >/tmp/genesis.json
mv /tmp/genesis.json "$CHAIN_DIR"/config/genesis.json
jq -r '.app_state.gov.voting_params.voting_period |= "30s"' "$CHAIN_DIR"/config/genesis.json >/tmp/genesis.json
mv /tmp/genesis.json "$CHAIN_DIR"/config/genesis.json
jq -r '.app_state.gov.tally_params.quorum |= "0.000000000000000000"' "$CHAIN_DIR"/config/genesis.json >/tmp/genesis.json
mv /tmp/genesis.json "$CHAIN_DIR"/config/genesis.json
jq -r '.app_state.gov.tally_params.threshold |= "0.000000000000000000"' "$CHAIN_DIR"/config/genesis.json >/tmp/genesis.json
mv /tmp/genesis.json "$CHAIN_DIR"/config/genesis.json
jq -r '.app_state.gov.tally_params.veto_threshold |= "0.000000000000000000"' "$CHAIN_DIR"/config/genesis.json >/tmp/genesis.json
mv /tmp/genesis.json "$CHAIN_DIR"/config/genesis.json
}
# overrides for newer sdk versions, post 0.47
function gov_overrides_sdk_v47() {
jq -r '.app_state.gov.params.max_deposit_period |= "30s"' "$CHAIN_DIR"/config/genesis.json >/tmp/genesis.json
mv /tmp/genesis.json "$CHAIN_DIR"/config/genesis.json
jq -r '.app_state.gov.params.min_deposit[0].amount |= "10"' "$CHAIN_DIR"/config/genesis.json >/tmp/genesis.json
mv /tmp/genesis.json "$CHAIN_DIR"/config/genesis.json
jq -r '.app_state.gov.params.voting_period |= "30s"' "$CHAIN_DIR"/config/genesis.json >/tmp/genesis.json
mv /tmp/genesis.json "$CHAIN_DIR"/config/genesis.json
jq -r '.app_state.gov.params.quorum |= "0.000000000000000000"' "$CHAIN_DIR"/config/genesis.json >/tmp/genesis.json
mv /tmp/genesis.json "$CHAIN_DIR"/config/genesis.json
jq -r '.app_state.gov.params.threshold |= "0.000000000000000000"' "$CHAIN_DIR"/config/genesis.json >/tmp/genesis.json
mv /tmp/genesis.json "$CHAIN_DIR"/config/genesis.json
jq -r '.app_state.gov.params.veto_threshold |= "0.000000000000000000"' "$CHAIN_DIR"/config/genesis.json >/tmp/genesis.json
mv /tmp/genesis.json "$CHAIN_DIR"/config/genesis.json
}
# EVM and feemarket configuration
if [ "$(jq -r '.app_state.evm' "$CHAIN_DIR"/config/genesis.json)" != "null" ]; then
jq -r ".app_state.evm.params.evm_denom |= \"$DENOM\"" "$CHAIN_DIR"/config/genesis.json >/tmp/genesis.json
mv /tmp/genesis.json "$CHAIN_DIR"/config/genesis.json
jq -r '.app_state.evm.params.active_static_precompiles |= ["0x0000000000000000000000000000000000000100","0x0000000000000000000000000000000000000400","0x0000000000000000000000000000000000000800","0x0000000000000000000000000000000000000801","0x0000000000000000000000000000000000000802","0x0000000000000000000000000000000000000803","0x0000000000000000000000000000000000000804","0x0000000000000000000000000000000000000805"]' "$CHAIN_DIR"/config/genesis.json >/tmp/genesis.json
mv /tmp/genesis.json "$CHAIN_DIR"/config/genesis.json
fi
if [ "$(jq -r '.app_state.erc20' "$CHAIN_DIR"/config/genesis.json)" != "null" ]; then
jq -r '.app_state.erc20.params.native_precompiles |= ["0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"]' "$CHAIN_DIR"/config/genesis.json >/tmp/genesis.json
mv /tmp/genesis.json "$CHAIN_DIR"/config/genesis.json
jq -r ".app_state.erc20.token_pairs |= [{\"contract_owner\":1,\"erc20_address\":\"0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE\",\"denom\":\"$DENOM\",\"enabled\":true}]" "$CHAIN_DIR"/config/genesis.json >/tmp/genesis.json
mv /tmp/genesis.json "$CHAIN_DIR"/config/genesis.json
fi
if [ "$(jq -r '.app_state.feemarket.params' "$CHAIN_DIR"/config/genesis.json)" != "null" ]; then
jq -r '.app_state.feemarket.params.no_base_fee |= true' "$CHAIN_DIR"/config/genesis.json >/tmp/genesis.json
mv /tmp/genesis.json "$CHAIN_DIR"/config/genesis.json
jq -r '.app_state.feemarket.params.base_fee |= "0.000000000000000000"' "$CHAIN_DIR"/config/genesis.json >/tmp/genesis.json
mv /tmp/genesis.json "$CHAIN_DIR"/config/genesis.json
fi
# Staking and mint configuration
if [ "$(jq -r '.app_state.staking' "$CHAIN_DIR"/config/genesis.json)" != "null" ]; then
jq -r ".app_state.staking.params.bond_denom |= \"$DENOM\"" "$CHAIN_DIR"/config/genesis.json >/tmp/genesis.json
mv /tmp/genesis.json "$CHAIN_DIR"/config/genesis.json
jq -r '.app_state.staking.params.min_commission_rate |= "0.050000000000000000"' "$CHAIN_DIR"/config/genesis.json >/tmp/genesis.json
mv /tmp/genesis.json "$CHAIN_DIR"/config/genesis.json
fi
if [ "$(jq -r '.app_state.mint' "$CHAIN_DIR"/config/genesis.json)" != "null" ]; then
jq -r ".app_state.mint.params.mint_denom |= \"$DENOM\"" "$CHAIN_DIR"/config/genesis.json >/tmp/genesis.json
mv /tmp/genesis.json "$CHAIN_DIR"/config/genesis.json
fi
if [ "$(jq -r '.app_state.crisis' "$CHAIN_DIR"/config/genesis.json)" != "null" ]; then
jq -r ".app_state.crisis.constant_fee |= {\"denom\":\"$DENOM\",\"amount\":\"1000\"}" "$CHAIN_DIR"/config/genesis.json >/tmp/genesis.json
mv /tmp/genesis.json "$CHAIN_DIR"/config/genesis.json
fi
# Token factory configuration
if [ "$(jq -r '.app_state.tokenfactory' "$CHAIN_DIR"/config/genesis.json)" != "null" ]; then
jq -r '.app_state.tokenfactory.params.denom_creation_fee |= []' "$CHAIN_DIR"/config/genesis.json >/tmp/genesis.json
mv /tmp/genesis.json "$CHAIN_DIR"/config/genesis.json
jq -r '.app_state.tokenfactory.params.denom_creation_gas_consume |= 100000' "$CHAIN_DIR"/config/genesis.json >/tmp/genesis.json
mv /tmp/genesis.json "$CHAIN_DIR"/config/genesis.json
fi
# ABCI configuration
if [ "$(jq -r '.consensus.params.abci' "$CHAIN_DIR"/config/genesis.json)" != "null" ]; then
jq -r '.consensus.params.abci.vote_extensions_enable_height |= "1"' "$CHAIN_DIR"/config/genesis.json >/tmp/genesis.json
mv /tmp/genesis.json "$CHAIN_DIR"/config/genesis.json
fi
# Add CONSTITUTION.md to governance if it exists
# Look for CONSTITUTION.md in the git root directory (parent of scripts directory)
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
GIT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
CONSTITUTION_FILE="${GIT_ROOT}/CONSTITUTION.md"
if [ -f "$CONSTITUTION_FILE" ]; then
echo "Adding CONSTITUTION.md to governance module from: $CONSTITUTION_FILE"
CONSTITUTION_CONTENT=$(cat "$CONSTITUTION_FILE" | jq -Rs .)
jq -r ".app_state.gov.constitution = $CONSTITUTION_CONTENT" "$CHAIN_DIR"/config/genesis.json >/tmp/genesis.json
mv /tmp/genesis.json "$CHAIN_DIR"/config/genesis.json
fi
if [ "$(jq -r '.app_state.gov.params' "$CHAIN_DIR"/config/genesis.json)" == "null" ]; then
gov_overrides_sdk_v46
else
gov_overrides_sdk_v47
fi
$CHAIN_BIN tendermint show-node-id
-53
View File
@@ -1,53 +0,0 @@
#!/bin/bash
set -e # Exit on any error
# Function to compare version strings
version_gt() {
test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1"
}
# Install commitizen if not present
if ! command -v cz &> /dev/null; then
echo "Installing commitizen..."
pip install --user commitizen
fi
# Get all tags and sort them by version
echo "Fetching all tags..."
git fetch --tags --force
TAGS=$(git tag -l "v*" | sort -V)
LATEST_TAG=$(echo "$TAGS" | tail -n1)
if [ -z "$LATEST_TAG" ]; then
echo "No tags found"
exit 1
fi
echo "Latest tag: $LATEST_TAG"
# Run commitizen to determine next version
echo "Running commitizen bump --dry-run..."
NEXT_VERSION=$(cz bump --dry-run --increment=patch 2>&1 | grep "tag to create: v" | cut -d "v" -f2)
if [ -z "$NEXT_VERSION" ]; then
echo "Failed to determine next version"
exit 1
fi
echo "Next version determined by commitizen: v$NEXT_VERSION"
# Check if the next version already exists
if echo "$TAGS" | grep -q "v$NEXT_VERSION"; then
echo "ERROR: Version v$NEXT_VERSION already exists!"
exit 1
fi
# Verify the next version is actually greater than the latest
if ! version_gt "$NEXT_VERSION" "${LATEST_TAG#v}"; then
echo "ERROR: Next version v$NEXT_VERSION is not greater than current version $LATEST_TAG"
exit 1
fi
echo "✅ Version v$NEXT_VERSION is valid and does not exist yet"
exit 0