diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index b82fcca..0b1db76 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -7,12 +7,56 @@ on: branches: [ "main" ] jobs: - build: - runs-on: ubuntu-latest + timeout-minutes: 3 steps: - - uses: actions/checkout@v3 - - name: Build the Docker image - run: docker build . --file Dockerfile --tag testnet-docker-image:$(date +%s) + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Docker Hub (if credentials available) + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + continue-on-error: true + + - name: Extract metadata + id: meta + shell: bash + run: | + set -euo pipefail + echo "tag=$(date +%s)" >> $GITHUB_OUTPUT + echo "sha=${GITHUB_SHA::8}" >> $GITHUB_OUTPUT + + - name: Build Docker image + uses: docker/build-push-action@v5 + with: + context: . + file: ./Dockerfile + tags: | + testnet-docker-image:${{ steps.meta.outputs.tag }} + testnet-docker-image:${{ steps.meta.outputs.sha }} + cache-from: type=gha + cache-to: type=gha,mode=max + push: false + load: true + + - name: Test Docker image + shell: bash + run: | + set -euo pipefail + docker images | grep testnet-docker-image + echo "Docker image built successfully" + + - name: Cleanup + if: always() + shell: bash + run: | + set -euo pipefail + docker system prune -f || true diff --git a/.github/workflows/test-start-node.yml b/.github/workflows/test-start-node.yml index f8bcf45..8195b49 100644 --- a/.github/workflows/test-start-node.yml +++ b/.github/workflows/test-start-node.yml @@ -9,35 +9,118 @@ on: jobs: test: runs-on: ubuntu-latest + timeout-minutes: 3 steps: - - uses: actions/checkout@v3 + - name: Checkout code + uses: actions/checkout@v4 - - name: Set up Docker - uses: docker/setup-buildx-action@v1 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 - - name: Install Docker Compose + - name: Verify Docker Compose + shell: bash run: | - sudo apt-get update - sudo apt-get install -y docker-compose + set -euo pipefail + if docker compose version >/dev/null 2>&1; then + echo "Using Docker Compose plugin" + docker compose version + elif command -v docker-compose >/dev/null 2>&1; then + echo "Using docker-compose standalone" + docker-compose --version + else + echo "Error: Docker Compose not available" + exit 1 + fi - - name: Start Preprod node, wait 30s then stop node + - name: Test Preprod node shell: bash + timeout-minutes: 10 run: | - printf "1\n" | /bin/bash ./start-node.sh 2>&1 | tee script_output.txt & + set -euo pipefail + printf "2\n1\n" | ./start-node.sh 2>&1 | tee preprod_output.txt & + START_PID=$! sleep 30 - /bin/bash ./stop-nodes.sh + if ! kill -0 $START_PID 2>/dev/null; then + echo "Error: start-node.sh process died unexpectedly" + exit 1 + fi + ./stop-nodes.sh + wait $START_PID || true + if [ -f preprod_output.txt ]; then + echo "=== Preprod Node Output ===" + cat preprod_output.txt + fi + + - name: Cleanup after Preprod + if: always() + shell: bash + run: | + set -euo pipefail + ./stop-nodes.sh || true + docker ps -a --filter "name=node-" --format "{{.Names}}" | xargs -r docker rm -f || true - - name: Start Preview node, wait 30s then stop node + - name: Test Preview node shell: bash + timeout-minutes: 3 run: | - printf "2\n" | /bin/bash ./start-node.sh 2>&1 | tee script_output.txt & + set -euo pipefail + printf "3\n1\n" | ./start-node.sh 2>&1 | tee preview_output.txt & + START_PID=$! sleep 30 - /bin/bash ./stop-nodes.sh + if ! kill -0 $START_PID 2>/dev/null; then + echo "Error: start-node.sh process died unexpectedly" + exit 1 + fi + ./stop-nodes.sh + wait $START_PID || true + if [ -f preview_output.txt ]; then + echo "=== Preview Node Output ===" + cat preview_output.txt + fi - - name: Start SanchoNet node, wait 30s then stop node + - name: Cleanup after Preview + if: always() shell: bash run: | - printf "3\n" | /bin/bash ./start-node.sh 2>&1 | tee script_output.txt & + set -euo pipefail + ./stop-nodes.sh || true + docker ps -a --filter "name=node-" --format "{{.Names}}" | xargs -r docker rm -f || true + + - name: Test SanchoNet node + shell: bash + timeout-minutes: 3 + run: | + set -euo pipefail + printf "4\n1\n" | ./start-node.sh 2>&1 | tee sancho_output.txt & + START_PID=$! sleep 30 - /bin/bash ./stop-nodes.sh \ No newline at end of file + if ! kill -0 $START_PID 2>/dev/null; then + echo "Error: start-node.sh process died unexpectedly" + exit 1 + fi + ./stop-nodes.sh + wait $START_PID || true + if [ -f sancho_output.txt ]; then + echo "=== SanchoNet Node Output ===" + cat sancho_output.txt + fi + + - name: Final cleanup + if: always() + shell: bash + run: | + set -euo pipefail + ./stop-nodes.sh || true + docker ps -a --filter "name=node-" --format "{{.Names}}" | xargs -r docker rm -f || true + docker system prune -f || true + + - name: Upload logs on failure + if: failure() + uses: actions/upload-artifact@v4 + with: + name: node-logs + path: | + *_output.txt + script_output.txt + retention-days: 7 \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index bea5e1c..820782e 100755 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -18,6 +18,7 @@ services: - ./keys:/keys - ./txs:/txs - ./dumps:/dumps + - ./utilities:/utilities logging: driver: "json-file" options: diff --git a/scripts/cc/authorize-hot-key.sh b/scripts/cc/authorize-hot-key.sh index 49f63d2..64a684e 100755 --- a/scripts/cc/authorize-hot-key.sh +++ b/scripts/cc/authorize-hot-key.sh @@ -1,16 +1,17 @@ #!/bin/bash -# Define directory paths -keys_dir="./keys" -txs_dir="./txs/cc" +# Get the script's directory and project root +script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" +txs_dir="$project_root/txs/cc" tx_path_stub="$txs_dir/auth-hot" tx_cert_path="$tx_path_stub.cert" tx_unsigned_path="$tx_path_stub.unsigned" tx_signed_path="$tx_path_stub.signed" -# Get the script's directory -script_dir=$(dirname "$0") - # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" diff --git a/scripts/cc/generate-cc-keys.sh b/scripts/cc/generate-cc-keys.sh index 2f8d8b5..abc044f 100755 --- a/scripts/cc/generate-cc-keys.sh +++ b/scripts/cc/generate-cc-keys.sh @@ -1,10 +1,11 @@ #!/bin/bash -# Define directories -keys_dir="./keys" - -# Get the script's directory +# Get the script's directory and project root script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" diff --git a/scripts/cc/generate-new-hot-key.sh b/scripts/cc/generate-new-hot-key.sh index faffd1a..0f1f781 100755 --- a/scripts/cc/generate-new-hot-key.sh +++ b/scripts/cc/generate-new-hot-key.sh @@ -1,10 +1,11 @@ #!/bin/bash -# Define directories -keys_dir="./keys" - -# Get the script's directory +# Get the script's directory and project root script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" diff --git a/scripts/cc/resign-cold-key.sh b/scripts/cc/resign-cold-key.sh index c06538f..11c20c4 100755 --- a/scripts/cc/resign-cold-key.sh +++ b/scripts/cc/resign-cold-key.sh @@ -1,17 +1,17 @@ #!/bin/bash -# Define directory paths -keys_dir="./keys" -txs_dir="./txs/cc" +# Get the script's directory and project root +script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" +txs_dir="$project_root/txs/cc" tx_path_stub="$txs_dir/resign-cold" tx_cert_path="$tx_path_stub.cert" tx_unsigned_path="$tx_path_stub.unsigned" tx_signed_path="$tx_path_stub.signed" - -# Get the script's directory -script_dir=$(dirname "$0") - # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" diff --git a/scripts/cc/vote.sh b/scripts/cc/vote.sh index 4df9519..8eab0a6 100755 --- a/scripts/cc/vote.sh +++ b/scripts/cc/vote.sh @@ -8,17 +8,18 @@ GA_TX_INDEX="0" # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Define directory paths -keys_dir="./keys" -txs_dir="./txs/cc" +# Get the script's directory and project root +script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" +txs_dir="$project_root/txs/cc" tx_path_stub="$txs_dir/cc-vote" tx_cert_path="$tx_path_stub.cert" tx_unsigned_path="$tx_path_stub.unsigned" tx_signed_path="$tx_path_stub.signed" -# Get the script's directory -script_dir=$(dirname "$0") - # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" diff --git a/scripts/drep/create-and-register-multisig.sh b/scripts/drep/create-and-register-multisig.sh index 0c24c0c..dc8b993 100755 --- a/scripts/drep/create-and-register-multisig.sh +++ b/scripts/drep/create-and-register-multisig.sh @@ -1,11 +1,12 @@ #!/bin/bash -# Define directories -keys_dir="./keys" -txs_dir="./txs/multi-sig" - -# Get the script's directory +# Get the script's directory and project root script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" +txs_dir="$project_root/txs/multi-sig" # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" diff --git a/scripts/drep/delegate-to-self.sh b/scripts/drep/delegate-to-self.sh index abd21ff..88d9e30 100755 --- a/scripts/drep/delegate-to-self.sh +++ b/scripts/drep/delegate-to-self.sh @@ -1,15 +1,45 @@ #!/bin/bash +set -euo pipefail -# Define directory paths -keys_dir="./keys" -txs_dir="./txs/drep" +# Get the script's directory and project root +script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" +txs_dir="$project_root/txs/drep" tx_path_stub="$txs_dir/vote-deleg-tx" tx_cert_path="$tx_path_stub.cert" tx_unsigned_path="$tx_path_stub.unsigned" tx_signed_path="$tx_path_stub.signed" -# Get the script's directory -script_dir=$(dirname "$0") +# Check required files exist +if [ ! -f "$keys_dir/drep.id" ]; then + echo "Error: DRep ID file not found: $keys_dir/drep.id" + echo "Please run scripts/generate-keys.sh first" + exit 1 +fi + +if [ ! -f "$keys_dir/payment.addr" ]; then + echo "Error: Payment address file not found: $keys_dir/payment.addr" + echo "Please run scripts/generate-keys.sh first" + exit 1 +fi + +if [ ! -f "$keys_dir/payment.skey" ]; then + echo "Error: Payment signing key not found: $keys_dir/payment.skey" + exit 1 +fi + +if [ ! -f "$keys_dir/stake.vkey" ]; then + echo "Error: Stake verification key not found: $keys_dir/stake.vkey" + exit 1 +fi + +if [ ! -f "$keys_dir/stake.skey" ]; then + echo "Error: Stake signing key not found: $keys_dir/stake.skey" + exit 1 +fi # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" @@ -23,34 +53,69 @@ echo "Using running container: $container_name" # Function to execute cardano-cli commands inside the container container_cli() { - docker exec -ti $container_name cardano-cli "$@" + docker exec -ti "$container_name" cardano-cli "$@" +} + +# Helper function to get UTXO with validation +get_utxo() { + local address=$1 + local utxo_output + utxo_output=$(container_cli conway query utxo --address "$address" --out-file /dev/stdout) + local utxo + utxo=$(echo "$utxo_output" | jq -r 'keys[0]') + if [ -z "$utxo" ] || [ "$utxo" = "null" ]; then + echo "Error: No UTXO found at address: $address" >&2 + exit 1 + fi + echo "$utxo" } -echo "Delegating your voting rights to your DRep ID ($(cat $keys_dir/drep.id))" +echo "Delegating your voting rights to your DRep ID ($(cat "$keys_dir/drep.id"))" container_cli conway stake-address vote-delegation-certificate \ - --stake-verification-key-file $keys_dir/stake.vkey \ - --drep-key-hash "$(cat $keys_dir/drep.id)" \ - --out-file $tx_cert_path + --stake-verification-key-file "$keys_dir/stake.vkey" \ + --drep-key-hash "$(cat "$keys_dir/drep.id")" \ + --out-file "$tx_cert_path" + +# Check certificate file was created +if [ ! -f "$tx_cert_path" ]; then + echo "Error: Failed to create certificate file" + exit 1 +fi echo "Building transaction" +payment_addr=$(cat "$keys_dir/payment.addr") +utxo=$(get_utxo "$payment_addr") + container_cli conway transaction build \ --witness-override 2 \ - --tx-in $(container_cli conway query utxo --address $(cat $keys_dir/payment.addr) --out-file /dev/stdout | jq -r 'keys[0]') \ - --change-address $(cat $keys_dir/payment.addr) \ - --certificate-file $tx_cert_path \ - --out-file $tx_unsigned_path + --tx-in "$utxo" \ + --change-address "$payment_addr" \ + --certificate-file "$tx_cert_path" \ + --out-file "$tx_unsigned_path" + +# Check transaction file was created +if [ ! -f "$tx_unsigned_path" ]; then + echo "Error: Failed to create unsigned transaction file" + exit 1 +fi echo "Signing transaction" container_cli conway transaction sign \ - --tx-body-file $tx_unsigned_path \ - --signing-key-file $keys_dir/payment.skey \ - --signing-key-file $keys_dir/stake.skey \ - --out-file $tx_signed_path + --tx-body-file "$tx_unsigned_path" \ + --signing-key-file "$keys_dir/payment.skey" \ + --signing-key-file "$keys_dir/stake.skey" \ + --out-file "$tx_signed_path" + +# Check signed transaction file was created +if [ ! -f "$tx_signed_path" ]; then + echo "Error: Failed to create signed transaction file" + exit 1 +fi # Submit the transaction echo "Submitting transaction" -container_cli conway transaction submit --tx-file $tx_signed_path \ No newline at end of file +container_cli conway transaction submit --tx-file "$tx_signed_path" \ No newline at end of file diff --git a/scripts/drep/register.sh b/scripts/drep/register.sh index ba00cbb..c8eb344 100755 --- a/scripts/drep/register.sh +++ b/scripts/drep/register.sh @@ -1,15 +1,40 @@ #!/bin/bash +set -euo pipefail -# Define directory paths -keys_dir="./keys" -txs_dir="./txs/drep" +# Get the script's directory and project root +script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" +txs_dir="$project_root/txs/drep" tx_path_stub="$txs_dir/drep-register-tx" tx_cert_path="$tx_path_stub.cert" tx_unsigned_path="$tx_path_stub.unsigned" tx_signed_path="$tx_path_stub.signed" -# Get the script's directory -script_dir=$(dirname "$0") +# Check required files exist +if [ ! -f "$keys_dir/drep.id" ]; then + echo "Error: DRep ID file not found: $keys_dir/drep.id" + echo "Please run scripts/generate-keys.sh first" + exit 1 +fi + +if [ ! -f "$keys_dir/payment.addr" ]; then + echo "Error: Payment address file not found: $keys_dir/payment.addr" + echo "Please run scripts/generate-keys.sh first" + exit 1 +fi + +if [ ! -f "$keys_dir/payment.skey" ]; then + echo "Error: Payment signing key not found: $keys_dir/payment.skey" + exit 1 +fi + +if [ ! -f "$keys_dir/drep.skey" ]; then + echo "Error: DRep signing key not found: $keys_dir/drep.skey" + exit 1 +fi # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" @@ -23,35 +48,70 @@ echo "Using running container: $container_name" # Function to execute cardano-cli commands inside the container container_cli() { - docker exec -ti $container_name cardano-cli "$@" + docker exec -ti "$container_name" cardano-cli "$@" +} + +# Helper function to get UTXO with validation +get_utxo() { + local address=$1 + local utxo_output + utxo_output=$(container_cli conway query utxo --address "$address" --out-file /dev/stdout) + local utxo + utxo=$(echo "$utxo_output" | jq -r 'keys[0]') + if [ -z "$utxo" ] || [ "$utxo" = "null" ]; then + echo "Error: No UTXO found at address: $address" >&2 + exit 1 + fi + echo "$utxo" } # Registering you as a drep echo "Registering you as a DRep." container_cli conway governance drep registration-certificate \ - --drep-key-hash "$(cat $keys_dir/drep.id)" \ - --key-reg-deposit-amt "$(container_cli conway query gov-state | jq -r .currentPParams.dRepDeposit)" \ - --out-file $tx_cert_path + --drep-key-hash "$(cat "$keys_dir/drep.id")" \ + --key-reg-deposit-amt "$(container_cli conway query gov-state | jq -r '.currentPParams.dRepDeposit')" \ + --out-file "$tx_cert_path" + +# Check certificate file was created +if [ ! -f "$tx_cert_path" ]; then + echo "Error: Failed to create certificate file" + exit 1 +fi echo "Building transaction" +payment_addr=$(cat "$keys_dir/payment.addr") +utxo=$(get_utxo "$payment_addr") + container_cli conway transaction build \ --witness-override 2 \ - --tx-in $(container_cli conway query utxo --address $(cat $keys_dir/payment.addr) --out-file /dev/stdout | jq -r 'keys[0]') \ - --change-address $(cat $keys_dir/payment.addr) \ - --certificate-file $tx_cert_path \ - --out-file $tx_unsigned_path + --tx-in "$utxo" \ + --change-address "$payment_addr" \ + --certificate-file "$tx_cert_path" \ + --out-file "$tx_unsigned_path" + +# Check transaction file was created +if [ ! -f "$tx_unsigned_path" ]; then + echo "Error: Failed to create unsigned transaction file" + exit 1 +fi echo "Signing transaction" container_cli conway transaction sign \ - --tx-body-file $tx_unsigned_path \ - --signing-key-file $keys_dir/payment.skey \ - --signing-key-file $keys_dir/drep.skey \ - --out-file $tx_signed_path + --tx-body-file "$tx_unsigned_path" \ + --signing-key-file "$keys_dir/payment.skey" \ + --signing-key-file "$keys_dir/drep.skey" \ + --out-file "$tx_signed_path" + +# Check signed transaction file was created +if [ ! -f "$tx_signed_path" ]; then + echo "Error: Failed to create signed transaction file" + exit 1 +fi # Submit the transaction echo "Submitting transaction" -container_cli conway transaction submit --tx-file $tx_signed_path \ No newline at end of file +container_cli conway transaction submit --tx-file "$tx_signed_path" \ No newline at end of file diff --git a/scripts/drep/retire.sh b/scripts/drep/retire.sh index fd08083..7226fb1 100755 --- a/scripts/drep/retire.sh +++ b/scripts/drep/retire.sh @@ -1,15 +1,40 @@ #!/bin/bash +set -euo pipefail -# Define directory paths -keys_dir="./keys" -txs_dir="./txs/drep" +# Get the script's directory and project root +script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" +txs_dir="$project_root/txs/drep" tx_path_stub="$txs_dir/drep-retire-tx" tx_cert_path="$tx_path_stub.cert" tx_unsigned_path="$tx_path_stub.unsigned" tx_signed_path="$tx_path_stub.signed" -# Get the script's directory -script_dir=$(dirname "$0") +# Check required files exist +if [ ! -f "$keys_dir/drep.id" ]; then + echo "Error: DRep ID file not found: $keys_dir/drep.id" + echo "Please run scripts/generate-keys.sh first" + exit 1 +fi + +if [ ! -f "$keys_dir/payment.addr" ]; then + echo "Error: Payment address file not found: $keys_dir/payment.addr" + echo "Please run scripts/generate-keys.sh first" + exit 1 +fi + +if [ ! -f "$keys_dir/payment.skey" ]; then + echo "Error: Payment signing key not found: $keys_dir/payment.skey" + exit 1 +fi + +if [ ! -f "$keys_dir/drep.skey" ]; then + echo "Error: DRep signing key not found: $keys_dir/drep.skey" + exit 1 +fi # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" @@ -23,35 +48,70 @@ echo "Using running container: $container_name" # Function to execute cardano-cli commands inside the container container_cli() { - docker exec -ti $container_name cardano-cli "$@" + docker exec -ti "$container_name" cardano-cli "$@" +} + +# Helper function to get UTXO with validation +get_utxo() { + local address=$1 + local utxo_output + utxo_output=$(container_cli conway query utxo --address "$address" --out-file /dev/stdout) + local utxo + utxo=$(echo "$utxo_output" | jq -r 'keys[0]') + if [ -z "$utxo" ] || [ "$utxo" = "null" ]; then + echo "Error: No UTXO found at address: $address" >&2 + exit 1 + fi + echo "$utxo" } # Retiring you as a drep echo "Retiring you as a DRep." container_cli conway governance drep retirement-certificate \ - --drep-key-hash $(cat $keys_dir/drep.id) \ - --deposit-amt $(container_cli conway query gov-state | jq -r .currentPParams.dRepDeposit) \ - --out-file $tx_cert_path + --drep-key-hash "$(cat "$keys_dir/drep.id")" \ + --deposit-amt "$(container_cli conway query gov-state | jq -r '.currentPParams.dRepDeposit')" \ + --out-file "$tx_cert_path" + +# Check certificate file was created +if [ ! -f "$tx_cert_path" ]; then + echo "Error: Failed to create certificate file" + exit 1 +fi echo "Building transaction" +payment_addr=$(cat "$keys_dir/payment.addr") +utxo=$(get_utxo "$payment_addr") + container_cli conway transaction build \ --witness-override 2 \ - --tx-in $(container_cli conway query utxo --address $(cat $keys_dir/payment.addr) --out-file /dev/stdout | jq -r 'keys[0]') \ - --change-address $(cat $keys_dir/payment.addr) \ - --certificate-file $tx_cert_path \ - --out-file $tx_unsigned_path + --tx-in "$utxo" \ + --change-address "$payment_addr" \ + --certificate-file "$tx_cert_path" \ + --out-file "$tx_unsigned_path" + +# Check transaction file was created +if [ ! -f "$tx_unsigned_path" ]; then + echo "Error: Failed to create unsigned transaction file" + exit 1 +fi echo "Signing transaction" container_cli conway transaction sign \ - --tx-body-file $tx_unsigned_path \ - --signing-key-file $keys_dir/payment.skey \ - --signing-key-file $keys_dir/drep.skey \ - --out-file $tx_signed_path + --tx-body-file "$tx_unsigned_path" \ + --signing-key-file "$keys_dir/payment.skey" \ + --signing-key-file "$keys_dir/drep.skey" \ + --out-file "$tx_signed_path" + +# Check signed transaction file was created +if [ ! -f "$tx_signed_path" ]; then + echo "Error: Failed to create signed transaction file" + exit 1 +fi # Submit the transaction echo "Submitting transaction" -container_cli conway transaction submit --tx-file $tx_signed_path +container_cli conway transaction submit --tx-file "$tx_signed_path" diff --git a/scripts/drep/vote.sh b/scripts/drep/vote.sh index 278505c..d5d0b9b 100755 --- a/scripts/drep/vote.sh +++ b/scripts/drep/vote.sh @@ -1,4 +1,5 @@ #!/bin/bash +set -euo pipefail # ~~~~~~~~~~~~ CHANGE THIS ~~~~~~~~~~~~ @@ -11,16 +12,39 @@ ANCHOR_HASH="5c783d31732ab3661a17879a41b0fd482a0d0befc63e7735641f7c82ba88f00e" # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Define directory paths -keys_dir="./keys" -txs_dir="./txs/drep" +# Get the script's directory and project root +script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" +txs_dir="$project_root/txs/drep" tx_path_stub="$txs_dir/drep-vote-tx" tx_cert_path="$tx_path_stub.vote" tx_unsigned_path="$tx_path_stub.unsigned" tx_signed_path="$tx_path_stub.signed" -# Get the script's directory -script_dir=$(dirname "$0") +# Check required files exist +if [ ! -f "$keys_dir/payment.addr" ]; then + echo "Error: Payment address file not found: $keys_dir/payment.addr" + echo "Please run scripts/generate-keys.sh first" + exit 1 +fi + +if [ ! -f "$keys_dir/payment.skey" ]; then + echo "Error: Payment signing key not found: $keys_dir/payment.skey" + exit 1 +fi + +if [ ! -f "$keys_dir/drep.vkey" ]; then + echo "Error: DRep verification key not found: $keys_dir/drep.vkey" + exit 1 +fi + +if [ ! -f "$keys_dir/drep.skey" ]; then + echo "Error: DRep signing key not found: $keys_dir/drep.skey" + exit 1 +fi # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" @@ -34,7 +58,21 @@ echo "Using running container: $container_name" # Function to execute cardano-cli commands inside the container container_cli() { - docker exec -ti $container_name cardano-cli "$@" + docker exec -ti "$container_name" cardano-cli "$@" +} + +# Helper function to get UTXO with validation +get_utxo() { + local address=$1 + local utxo_output + utxo_output=$(container_cli conway query utxo --address "$address" --out-file /dev/stdout) + local utxo + utxo=$(echo "$utxo_output" | jq -r 'keys[0]') + if [ -z "$utxo" ] || [ "$utxo" = "null" ]; then + echo "Error: No UTXO found at address: $address" >&2 + exit 1 + fi + echo "$utxo" } # Voting on a governance action @@ -44,30 +82,51 @@ container_cli conway governance vote create \ "--$CHOICE" \ --governance-action-tx-id "$GA_TX_HASH" \ --governance-action-index "$GA_TX_INDEX" \ - --drep-verification-key-file $keys_dir/drep.vkey \ + --drep-verification-key-file "$keys_dir/drep.vkey" \ --anchor-data-hash "$ANCHOR_HASH" \ --anchor-url "$ANCHOR_URI" \ --check-anchor-data-hash \ - --out-file $tx_cert_path + --out-file "$tx_cert_path" + +# Check certificate file was created +if [ ! -f "$tx_cert_path" ]; then + echo "Error: Failed to create certificate file" + exit 1 +fi echo "Building transaction" +payment_addr=$(cat "$keys_dir/payment.addr") +utxo=$(get_utxo "$payment_addr") + container_cli conway transaction build \ - --tx-in "$(container_cli conway query utxo --address "$(cat $keys_dir/payment.addr)" --out-file /dev/stdout | jq -r 'keys[0]')" \ - --change-address "$(cat $keys_dir/payment.addr)" \ - --vote-file $tx_cert_path \ + --tx-in "$utxo" \ + --change-address "$payment_addr" \ + --vote-file "$tx_cert_path" \ --witness-override 2 \ - --out-file $tx_unsigned_path + --out-file "$tx_unsigned_path" + +# Check transaction file was created +if [ ! -f "$tx_unsigned_path" ]; then + echo "Error: Failed to create unsigned transaction file" + exit 1 +fi echo "Signing transaction" container_cli conway transaction sign \ - --tx-body-file $tx_unsigned_path \ - --signing-key-file $keys_dir/drep.skey \ - --signing-key-file $keys_dir/payment.skey \ - --out-file $tx_signed_path + --tx-body-file "$tx_unsigned_path" \ + --signing-key-file "$keys_dir/drep.skey" \ + --signing-key-file "$keys_dir/payment.skey" \ + --out-file "$tx_signed_path" + +# Check signed transaction file was created +if [ ! -f "$tx_signed_path" ]; then + echo "Error: Failed to create signed transaction file" + exit 1 +fi # Submit the transaction echo "Submitting transaction" -container_cli conway transaction submit --tx-file $tx_signed_path +container_cli conway transaction submit --tx-file "$tx_signed_path" diff --git a/scripts/ga/hardfork.sh b/scripts/ga/hardfork.sh index 99ce1fb..42757b2 100755 --- a/scripts/ga/hardfork.sh +++ b/scripts/ga/hardfork.sh @@ -8,17 +8,18 @@ METADATA_URL="https://raw.githubusercontent.com/IntersectMBO/governance-actions/ METADATA_HASH="8a1bd37caa6b914a8b569adb63a0f41d8f159c110dc5c8409118a3f087fffb43" # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Define directory paths -keys_dir="./keys" -txs_dir="./txs/ga" +# Get the script's directory and project root +script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" +txs_dir="$project_root/txs/ga" tx_path_stub="$txs_dir/hardfork" tx_cert_path="$tx_path_stub.action" tx_unsigned_path="$tx_path_stub.unsigned" tx_signed_path="$tx_path_stub.signed" -# Get the script's directory -script_dir=$(dirname "$0") - # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" @@ -72,7 +73,7 @@ echo "Signing transaction" container_cli conway transaction sign \ --tx-body-file "$tx_unsigned_path" \ --signing-key-file $keys_dir/payment.skey \ - --out-file "$tx_unsigned_path" + --out-file "$tx_signed_path" # Submit the transaction echo "Submitting transaction" diff --git a/scripts/ga/info.sh b/scripts/ga/info.sh index 7a44ef9..bafd0ff 100755 --- a/scripts/ga/info.sh +++ b/scripts/ga/info.sh @@ -1,4 +1,5 @@ #!/bin/bash +set -euo pipefail # ~~~~~~~~~~~~ CHANGE THIS ~~~~~~~~~~~~ @@ -7,16 +8,34 @@ METADATA_HASH="2df56fcaaa6d6bd73e792b871b746cd9c6209e95a2f0e6344502be9f7abf5567" # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Define directory paths -keys_dir="./keys" -txs_dir="./txs/ga" +# Get the script's directory and project root +script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" +txs_dir="$project_root/txs/ga" tx_path_stub="$txs_dir/info" tx_cert_path="$tx_path_stub.action" tx_unsigned_path="$tx_path_stub.unsigned" tx_signed_path="$tx_path_stub.signed" -# Get the script's directory -script_dir=$(dirname "$0") +# Check required files exist +if [ ! -f "$keys_dir/payment.addr" ]; then + echo "Error: Payment address file not found: $keys_dir/payment.addr" + echo "Please run scripts/generate-keys.sh first" + exit 1 +fi + +if [ ! -f "$keys_dir/payment.skey" ]; then + echo "Error: Payment signing key not found: $keys_dir/payment.skey" + exit 1 +fi + +if [ ! -f "$keys_dir/stake.vkey" ]; then + echo "Error: Stake verification key not found: $keys_dir/stake.vkey" + exit 1 +fi # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" @@ -30,7 +49,21 @@ echo "Using running container: $container_name" # Function to execute cardano-cli commands inside the container container_cli() { - docker exec -ti $container_name cardano-cli "$@" + docker exec -ti "$container_name" cardano-cli "$@" +} + +# Helper function to get UTXO with validation +get_utxo() { + local address=$1 + local utxo_output + utxo_output=$(container_cli conway query utxo --address "$address" --out-file /dev/stdout) + local utxo + utxo=$(echo "$utxo_output" | jq -r 'keys[0]') + if [ -z "$utxo" ] || [ "$utxo" = "null" ]; then + echo "Error: No UTXO found at address: $address" >&2 + exit 1 + fi + echo "$utxo" } # Building, signing and submitting an info governance action @@ -38,29 +71,50 @@ echo "Creating and submitting info governance action." container_cli conway governance action create-info \ --testnet \ - --governance-action-deposit $(container_cli conway query gov-state | jq -r '.currentPParams.govActionDeposit') \ - --deposit-return-stake-verification-key-file $keys_dir/stake.vkey \ - --anchor-url $METADATA_URL \ - --anchor-data-hash $METADATA_HASH \ + --governance-action-deposit "$(container_cli conway query gov-state | jq -r '.currentPParams.govActionDeposit')" \ + --deposit-return-stake-verification-key-file "$keys_dir/stake.vkey" \ + --anchor-url "$METADATA_URL" \ + --anchor-data-hash "$METADATA_HASH" \ --check-anchor-data \ --out-file "$tx_cert_path" +# Check certificate file was created +if [ ! -f "$tx_cert_path" ]; then + echo "Error: Failed to create certificate file" + exit 1 +fi + echo "Building transaction" +payment_addr=$(cat "$keys_dir/payment.addr") +utxo=$(get_utxo "$payment_addr") + container_cli conway transaction build \ - --tx-in "$(container_cli conway query utxo --address "$(cat $keys_dir/payment.addr)" --out-file /dev/stdout | jq -r 'keys[0]')" \ - --change-address "$(cat $keys_dir/payment.addr)" \ + --tx-in "$utxo" \ + --change-address "$payment_addr" \ --proposal-file "$tx_cert_path" \ --out-file "$tx_unsigned_path" +# Check transaction file was created +if [ ! -f "$tx_unsigned_path" ]; then + echo "Error: Failed to create unsigned transaction file" + exit 1 +fi + echo "Signing transaction" container_cli conway transaction sign \ --tx-body-file "$tx_unsigned_path" \ - --signing-key-file $keys_dir/payment.skey \ + --signing-key-file "$keys_dir/payment.skey" \ --out-file "$tx_signed_path" +# Check signed transaction file was created +if [ ! -f "$tx_signed_path" ]; then + echo "Error: Failed to create signed transaction file" + exit 1 +fi + # Submit the transaction echo "Submitting transaction" -container_cli conway transaction submit --tx-file $tx_signed_path +container_cli conway transaction submit --tx-file "$tx_signed_path" diff --git a/scripts/ga/new-committee.sh b/scripts/ga/new-committee.sh index 5c706aa..507ae2f 100755 --- a/scripts/ga/new-committee.sh +++ b/scripts/ga/new-committee.sh @@ -8,17 +8,18 @@ METADATA_URL="ipfs://bafkreia4ahcsnfegacpxypsgo2gpno5did6grm7ipqa6k2kivzsctlwlau METADATA_HASH="fd23ef0b70a2feaf8229aa1df79ed77f18b07881e35237a569730b2b261b99fc" # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Define directory paths -keys_dir="./keys" -txs_dir="./txs/ga" +# Get the script's directory and project root +script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" +txs_dir="$project_root/txs/ga" tx_path_stub="$txs_dir/new-committee" tx_cert_path="$tx_path_stub.action" tx_unsigned_path="$tx_path_stub.unsigned" tx_signed_path="$tx_path_stub.signed" -# Get the script's directory -script_dir=$(dirname "$0") - # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" diff --git a/scripts/ga/new-consitution.sh b/scripts/ga/new-consitution.sh index 9e656b4..c8b3e9d 100755 --- a/scripts/ga/new-consitution.sh +++ b/scripts/ga/new-consitution.sh @@ -10,17 +10,18 @@ METADATA_URL="https://raw.githubusercontent.com/IntersectMBO/governance-actions/ METADATA_HASH="4b2649556c838497ee2923bdff0f05b48fb2f0c3c5cceb450200f8bd6868ac5b" # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Define directory paths -keys_dir="./keys" -txs_dir="./txs/ga" +# Get the script's directory and project root +script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" +txs_dir="$project_root/txs/ga" tx_path_stub="$txs_dir/new-constitution" tx_cert_path="$tx_path_stub.action" tx_unsigned_path="$tx_path_stub.unsigned" tx_signed_path="$tx_path_stub.signed" -# Get the script's directory -script_dir=$(dirname "$0") - # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" @@ -36,12 +37,12 @@ container_cli() { docker exec -ti $container_name cardano-cli "$@" } -# echo "Finding the previous Constitution GA to reference" +echo "Finding the previous Constitution GA to reference" -# GOV_STATE=$(container_cli conway query gov-state | jq -r '.nextRatifyState.nextEnactState.prevGovActionIds') +GOV_STATE=$(container_cli conway query gov-state | jq -r '.nextRatifyState.nextEnactState.prevGovActionIds') -# PREV_GA_TX_HASH=$(echo "$GOV_STATE" | jq -r '.Constitution.txId') -# PREV_GA_INDEX=$(echo "$GOV_STATE" | jq -r '.Constitution.govActionIx') +PREV_GA_TX_HASH=$(echo "$GOV_STATE" | jq -r '.Constitution.txId') +PREV_GA_INDEX=$(echo "$GOV_STATE" | jq -r '.Constitution.govActionIx') echo "Previous Constitution GA Tx Hash: $PREV_GA_TX_HASH#$PREV_GA_INDEX" @@ -59,11 +60,10 @@ container_cli conway governance action create-constitution \ --constitution-hash "$NEW_CONSTITUTION_ANCHOR_HASH" \ --check-constitution-hash \ --constitution-script-hash "$NEW_CONSTITUTION_SCRIPT_HASH" \ + --prev-governance-action-tx-id "$PREV_GA_TX_HASH" \ + --prev-governance-action-index "$PREV_GA_INDEX" \ --out-file "$tx_cert_path" - # --prev-governance-action-tx-id "$PREV_GA_TX_HASH" \ - # --prev-governance-action-index "$PREV_GA_INDEX" \ - echo "Building transaction" container_cli conway transaction build \ @@ -75,7 +75,7 @@ container_cli conway transaction build \ echo "Signing transaction" container_cli conway transaction sign \ - --tx-body-file "$tx_unigned_path" \ + --tx-body-file "$tx_unsigned_path" \ --signing-key-file $keys_dir/payment.skey \ --out-file "$tx_signed_path" diff --git a/scripts/ga/no-confidence.sh b/scripts/ga/no-confidence.sh index 35e079d..b9fe80a 100755 --- a/scripts/ga/no-confidence.sh +++ b/scripts/ga/no-confidence.sh @@ -8,17 +8,18 @@ METADATA_URL="https://raw.githubusercontent.com/IntersectMBO/governance-actions/ METADATA_HASH="ab901c3aeeca631ee5c70147a558fbf191a4af245d8ca001e845d8569d7c38f9" # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Define directory paths -keys_dir="./keys" -txs_dir="./txs/ga" +# Get the script's directory and project root +script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" +txs_dir="$project_root/txs/ga" tx_path_stub="$txs_dir/no-confidence" tx_cert_path="$tx_path_stub.action" tx_unsigned_path="$tx_path_stub.unsigned" tx_signed_path="$tx_path_stub.signed" -# Get the script's directory -script_dir=$(dirname "$0") - # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" diff --git a/scripts/ga/parameter.sh b/scripts/ga/parameter.sh index d4753f7..c9f4adb 100755 --- a/scripts/ga/parameter.sh +++ b/scripts/ga/parameter.sh @@ -5,19 +5,18 @@ METADATA_URL="ipfs://bafkreia5vseqm3hqmds45gje4szvekwkzd4mebzeepbh2cdlr3krxcj2ou METADATA_HASH="dfa2df398319b48e80a2caf02f4165bf12b6689d0ed57eee5e13dfa94857ed71" # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Define directory paths -keys_dir="./keys" -txs_dir="./txs/ga" +# Get the script's directory and project root +script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" +txs_dir="$project_root/txs/ga" tx_path_stub="$txs_dir/parameter-change" tx_cert_path="$tx_path_stub.action" tx_unsigned_path="$tx_path_stub.unsigned" tx_signed_path="$tx_path_stub.signed" -guardrails_script_path="./config/guardrails-script.plutus" - -# Get the script's directory -script_dir=$(dirname "$0") - # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" @@ -28,6 +27,11 @@ fi echo "Using running container: $container_name" +# Extract network and version from container name (format: node-network-version-container) +network=$(echo $container_name | cut -d'-' -f2) +version=$(echo $container_name | cut -d'-' -f3) +guardrails_script_path="$project_root/node-$network-$version/config/guardrails-script.plutus" + # Function to execute cardano-cli commands inside the container container_cli() { docker exec -ti $container_name cardano-cli "$@" diff --git a/scripts/ga/treasury.sh b/scripts/ga/treasury.sh index bf7f673..a2cbaae 100755 --- a/scripts/ga/treasury.sh +++ b/scripts/ga/treasury.sh @@ -11,19 +11,18 @@ METADATA_HASH="91a36ac3cc4b563a407e7a86139fee9e7e2b2a6511617b96ba3165ccddf5a5b3" # treat unset variables as an error, and fail if any command in a pipeline fails set -euo pipefail -# Define directory paths -keys_dir="./keys" -txs_dir="./txs/ga" +# Get the script's directory and project root +script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" +txs_dir="$project_root/txs/ga" tx_path_stub="$txs_dir/treasury-withdrawal" tx_cert_path="$tx_path_stub.action" tx_unsigned_path="$tx_path_stub.unsigned" tx_signed_path="$tx_path_stub.signed" -guardrails_script_path="./config/guardrails-script.plutus" - -# Get the script's directory -script_dir=$(dirname "$0") - # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" @@ -34,6 +33,11 @@ fi echo "Using running container: $container_name" +# Extract network and version from container name (format: node-network-version-container) +network=$(echo $container_name | cut -d'-' -f2) +version=$(echo $container_name | cut -d'-' -f3) +guardrails_script_path="$project_root/node-$network-$version/config/guardrails-script.plutus" + # Function to execute cardano-cli commands inside the container container_cli() { docker exec -ti $container_name cardano-cli "$@" diff --git a/scripts/generate-keys.sh b/scripts/generate-keys.sh index dfd5d05..1091bee 100755 --- a/scripts/generate-keys.sh +++ b/scripts/generate-keys.sh @@ -1,10 +1,15 @@ #!/bin/bash +set -euo pipefail -# Define the keys directory -keys_dir="./keys" - -# Get the script's directory +# Get the script's directory and project root script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" + +# Create keys directory if it doesn't exist +mkdir -p "$keys_dir" # Get the container name from the get-container script container_name="$("$script_dir/helper/get-container.sh")" @@ -14,9 +19,9 @@ if [ -z "$container_name" ]; then exit 1 fi -network=$(echo $container_name | cut -d'-' -f2) +network=$(echo "$container_name" | cut -d'-' -f2) -if [ $network = "mainnet" ]; then +if [ "$network" = "mainnet" ]; then echo "These scripts are not secure and should not be used to create mainnet transactions!!" echo "Exiting." exit 0 @@ -26,7 +31,7 @@ echo "Using running container: $container_name" # Function to execute cardano-cli commands inside the container container_cli() { - docker exec -ti $container_name cardano-cli "$@" + docker exec -ti "$container_name" cardano-cli "$@" } # Check if keys already exist diff --git a/scripts/helper/combine-utxos.sh b/scripts/helper/combine-utxos.sh index 44dd662..01a6df5 100755 --- a/scripts/helper/combine-utxos.sh +++ b/scripts/helper/combine-utxos.sh @@ -1,11 +1,25 @@ #!/bin/bash +set -euo pipefail -# Define directories -keys_dir="./keys" -txs_dir="./txs/" - -# Get the script's directory +# Get the script's directory and project root script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" +txs_dir="$project_root/txs/helper" + +# Check required files exist +if [ ! -f "$keys_dir/payment.addr" ]; then + echo "Error: Payment address file not found: $keys_dir/payment.addr" + echo "Please run scripts/generate-keys.sh first" + exit 1 +fi + +if [ ! -f "$keys_dir/payment.skey" ]; then + echo "Error: Payment signing key not found: $keys_dir/payment.skey" + exit 1 +fi # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" @@ -19,27 +33,43 @@ echo "Using running container: $container_name" # Function to execute cardano-cli commands inside the container container_cli() { - docker exec -ti $container_name cardano-cli "$@" + docker exec -ti "$container_name" cardano-cli "$@" } -echo "Combining all only ada UTxOs at $(cat "$keys_dir/payment.addr")" +payment_addr=$(cat "$keys_dir/payment.addr") +echo "Combining all only ada UTxOs at $payment_addr" # build transaction +tx_unsigned="$txs_dir/combine-utxos-tx.unsigned" +tx_signed="$txs_dir/combine-utxos-tx.signed" + container_cli conway transaction build \ - $(container_cli query utxo --address $(cat "$keys_dir/payment.addr") --out-file /dev/stdout \ + $(container_cli conway query utxo --address "$payment_addr" --out-file /dev/stdout \ | jq -r 'to_entries | map(select(.value.datum == null and .value.datumhash == null and .value.inlineDatum == null and .value.inlineDatumRaw == null and .value.referenceScript == null)) | map(" --tx-in " + .key) | .[]') \ - --change-address $(cat "$keys_dir/payment.addr") \ - --out-file "$txs_dir/combine-utxos-tx.unsigned" + --change-address "$payment_addr" \ + --out-file "$tx_unsigned" + +# Check transaction file was created +if [ ! -f "$tx_unsigned" ]; then + echo "Error: Failed to create unsigned transaction file" + exit 1 +fi # Sign transaction container_cli conway transaction sign \ - --tx-body-file "$txs_dir/combine-utxos-tx.unsigned" \ + --tx-body-file "$tx_unsigned" \ --signing-key-file "$keys_dir/payment.skey" \ - --out-file "$txs_dir/combine-utxos-tx.signed" + --out-file "$tx_signed" + +# Check signed transaction file was created +if [ ! -f "$tx_signed" ]; then + echo "Error: Failed to create signed transaction file" + exit 1 +fi # Submit transaction container_cli conway transaction submit \ - --tx-file "$txs_dir/combine-utxos-tx.signed" + --tx-file "$tx_signed" diff --git a/scripts/helper/get-container.sh b/scripts/helper/get-container.sh index dd9197b..0ae075e 100755 --- a/scripts/helper/get-container.sh +++ b/scripts/helper/get-container.sh @@ -1,4 +1,5 @@ #!/bin/bash +# set -euo pipefail # Get the list of running containers running_containers=$(docker ps --format '{{.Names}}') diff --git a/scripts/helper/sign-submit-tx.sh b/scripts/helper/sign-submit-tx.sh index 6c01e3f..a139bbb 100755 --- a/scripts/helper/sign-submit-tx.sh +++ b/scripts/helper/sign-submit-tx.sh @@ -1,18 +1,31 @@ #!/bin/bash +set -euo pipefail # ~~~~~~~~~~~~ CHANGE THIS ~~~~~~~~~~~~ TRANSACTION_FILE="treasury-contract" # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Define directory paths -keys_dir="./keys" -txs_dir="./txs" +# Get the script's directory and project root +script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" +txs_dir="$project_root/txs" tx_unsigned_path="$txs_dir/$TRANSACTION_FILE.unsigned" tx_signed_path="$txs_dir/$TRANSACTION_FILE.signed" -# Get the script's directory -script_dir=$(dirname "$0") +# Check required files exist +if [ ! -f "$tx_unsigned_path" ]; then + echo "Error: Unsigned transaction file not found: $tx_unsigned_path" + exit 1 +fi + +if [ ! -f "$keys_dir/payment.skey" ]; then + echo "Error: Payment signing key not found: $keys_dir/payment.skey" + exit 1 +fi # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" @@ -26,7 +39,7 @@ echo "Using running container: $container_name" # Function to execute cardano-cli commands inside the container container_cli() { - docker exec -ti $container_name cardano-cli "$@" + docker exec -ti "$container_name" cardano-cli "$@" } # Send ada to the multisig payment script @@ -34,10 +47,16 @@ echo "Signing and submitting $tx_unsigned_path transaction." container_cli conway transaction sign \ --tx-body-file "$tx_unsigned_path" \ - --signing-key-file $keys_dir/payment.skey \ + --signing-key-file "$keys_dir/payment.skey" \ --out-file "$tx_signed_path" +# Check signed transaction file was created +if [ ! -f "$tx_signed_path" ]; then + echo "Error: Failed to create signed transaction file" + exit 1 +fi + # Submit the transaction echo "Submitting transaction" -container_cli conway transaction submit --tx-file $tx_signed_path +container_cli conway transaction submit --tx-file "$tx_signed_path" diff --git a/scripts/multi-sig/create-info-action.sh b/scripts/multi-sig/create-info-action.sh index c117599..cf4713b 100755 --- a/scripts/multi-sig/create-info-action.sh +++ b/scripts/multi-sig/create-info-action.sh @@ -1,20 +1,61 @@ #!/bin/bash +set -euo pipefail # ~~~~~~~~~~~~ CHANGE THIS ~~~~~~~~~~~~ METADATA_URL="https://buy-ryan-an-island.com" METADATA_HASH="0000000000000000000000000000000000000000000000000000000000000000" # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Define directory paths -keys_dir="./keys" -txs_dir="./txs/multi-sig" +# Get the script's directory and project root +script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" +txs_dir="$project_root/txs/multi-sig" tx_path_stub="$txs_dir/info-action" tx_cert_path="$tx_path_stub.action" tx_unsigned_path="$tx_path_stub.unsigned" tx_signed_path="$tx_path_stub.signed" -# Get the script's directory -script_dir=$(dirname "$0") +# Check required files exist +if [ ! -f "$keys_dir/multi-sig/script.addr" ]; then + echo "Error: Multi-sig script address not found: $keys_dir/multi-sig/script.addr" + echo "Please run scripts/multi-sig/generate-keys-and-script.sh first" + exit 1 +fi + +if [ ! -f "$keys_dir/multi-sig/script.json" ]; then + echo "Error: Multi-sig script JSON not found: $keys_dir/multi-sig/script.json" + exit 1 +fi + +if [ ! -f "$keys_dir/payment.addr" ]; then + echo "Error: Payment address file not found: $keys_dir/payment.addr" + echo "Please run scripts/generate-keys.sh first" + exit 1 +fi + +if [ ! -f "$keys_dir/stake.vkey" ]; then + echo "Error: Stake verification key not found: $keys_dir/stake.vkey" + exit 1 +fi + +for i in 1 2 3; do + if [ ! -f "$keys_dir/multi-sig/$i.skey" ]; then + echo "Error: Multi-sig signing key $i not found: $keys_dir/multi-sig/$i.skey" + exit 1 + fi + if [ ! -f "$keys_dir/multi-sig/$i.keyhash" ]; then + echo "Error: Multi-sig keyhash $i not found: $keys_dir/multi-sig/$i.keyhash" + exit 1 + fi +done + +if [ ! -f "$keys_dir/payment.skey" ]; then + echo "Error: Payment signing key not found: $keys_dir/payment.skey" + exit 1 +fi # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" @@ -28,7 +69,21 @@ echo "Using running container: $container_name" # Function to execute cardano-cli commands inside the container container_cli() { - docker exec -ti $container_name cardano-cli "$@" + docker exec -ti "$container_name" cardano-cli "$@" +} + +# Helper function to get UTXO with validation +get_utxo() { + local address=$1 + local utxo_output + utxo_output=$(container_cli conway query utxo --address "$address" --out-file /dev/stdout) + local utxo + utxo=$(echo "$utxo_output" | jq -r 'keys[0]') + if [ -z "$utxo" ] || [ "$utxo" = "null" ]; then + echo "Error: No UTXO found at address: $address" >&2 + exit 1 + fi + echo "$utxo" } # Building, signing and submitting an info governance action @@ -36,57 +91,80 @@ echo "Creating and submitting info governance action, using the multi-sig's ada. container_cli conway governance action create-info \ --testnet \ - --governance-action-deposit $(container_cli conway query gov-state | jq -r '.currentPParams.govActionDeposit') \ - --deposit-return-stake-verification-key-file $keys_dir/stake.vkey \ + --governance-action-deposit "$(container_cli conway query gov-state | jq -r '.currentPParams.govActionDeposit')" \ + --deposit-return-stake-verification-key-file "$keys_dir/stake.vkey" \ --anchor-url "$METADATA_URL" \ --anchor-data-hash "$METADATA_HASH" \ --out-file "$tx_cert_path" +# Check certificate file was created +if [ ! -f "$tx_cert_path" ]; then + echo "Error: Failed to create certificate file" + exit 1 +fi + echo "Building transaction" +script_addr=$(cat "$keys_dir/multi-sig/script.addr") +payment_addr=$(cat "$keys_dir/payment.addr") +script_utxo=$(get_utxo "$script_addr") +payment_utxo=$(get_utxo "$payment_addr") + container_cli conway transaction build \ - --tx-in "$(container_cli conway query utxo --address "$(cat $keys_dir/multi-sig/script.addr)" --out-file /dev/stdout | jq -r 'keys[0]')" \ - --tx-in-script-file $keys_dir/multi-sig/script.json \ - --tx-in "$(container_cli conway query utxo --address "$(cat $keys_dir/payment.addr)" --out-file /dev/stdout | jq -r 'keys[0]')" \ - --change-address "$(cat $keys_dir/payment.addr)" \ + --tx-in "$script_utxo" \ + --tx-in-script-file "$keys_dir/multi-sig/script.json" \ + --tx-in "$payment_utxo" \ + --change-address "$payment_addr" \ --proposal-file "$tx_cert_path" \ - --required-signer-hash "$(cat $keys_dir/multi-sig/1.keyhash)" \ - --required-signer-hash "$(cat $keys_dir/multi-sig/2.keyhash)" \ - --required-signer-hash "$(cat $keys_dir/multi-sig/3.keyhash)" \ + --required-signer-hash "$(cat "$keys_dir/multi-sig/1.keyhash")" \ + --required-signer-hash "$(cat "$keys_dir/multi-sig/2.keyhash")" \ + --required-signer-hash "$(cat "$keys_dir/multi-sig/3.keyhash")" \ --out-file "$tx_unsigned_path" +# Check transaction file was created +if [ ! -f "$tx_unsigned_path" ]; then + echo "Error: Failed to create unsigned transaction file" + exit 1 +fi + # Create multisig witnesses container_cli conway transaction witness \ --tx-body-file "$tx_unsigned_path" \ - --signing-key-file $keys_dir/multi-sig/1.skey \ + --signing-key-file "$keys_dir/multi-sig/1.skey" \ --out-file "$tx_path_stub-1.witness" container_cli conway transaction witness \ --tx-body-file "$tx_unsigned_path" \ - --signing-key-file $keys_dir/multi-sig/2.skey \ + --signing-key-file "$keys_dir/multi-sig/2.skey" \ --out-file "$tx_path_stub-2.witness" container_cli conway transaction witness \ --tx-body-file "$tx_unsigned_path" \ - --signing-key-file $keys_dir/multi-sig/3.skey \ + --signing-key-file "$keys_dir/multi-sig/3.skey" \ --out-file "$tx_path_stub-3.witness" # Create witness container_cli conway transaction witness \ --tx-body-file "$tx_unsigned_path" \ - --signing-key-file $keys_dir/payment.skey \ + --signing-key-file "$keys_dir/payment.skey" \ --out-file "$tx_path_stub-payment.witness" # Assemble Transaction container_cli conway transaction assemble \ --tx-body-file "$tx_unsigned_path" \ --witness-file "$tx_path_stub-payment.witness" \ + --witness-file "$tx_path_stub-1.witness" \ --witness-file "$tx_path_stub-2.witness" \ --witness-file "$tx_path_stub-3.witness" \ - --witness-file "$tx_path_stub-3.witness" \ --out-file "$tx_signed_path" +# Check signed transaction file was created +if [ ! -f "$tx_signed_path" ]; then + echo "Error: Failed to create signed transaction file" + exit 1 +fi + # Submit the transaction echo "Submitting transaction" -container_cli conway transaction submit --tx-file $tx_signed_path +container_cli conway transaction submit --tx-file "$tx_signed_path" diff --git a/scripts/multi-sig/create-param-action.sh b/scripts/multi-sig/create-param-action.sh index 847ee4b..3d6dcfe 100755 --- a/scripts/multi-sig/create-param-action.sh +++ b/scripts/multi-sig/create-param-action.sh @@ -1,20 +1,61 @@ #!/bin/bash +set -euo pipefail # ~~~~~~~~~~~~ CHANGE THIS ~~~~~~~~~~~~ METADATA_URL="https://buy-ryan-an-island.com" METADATA_HASH="0000000000000000000000000000000000000000000000000000000000000000" # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Define directory paths -keys_dir="./keys" -txs_dir="./txs/multi-sig" +# Get the script's directory and project root +script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" +txs_dir="$project_root/txs/multi-sig" tx_path_stub="$txs_dir/param-change-action" tx_cert_path="$tx_path_stub.action" tx_unsigned_path="$tx_path_stub.unsigned" tx_signed_path="$tx_path_stub.signed" -# Get the script's directory -script_dir=$(dirname "$0") +# Check required files exist +if [ ! -f "$keys_dir/multi-sig/script.addr" ]; then + echo "Error: Multi-sig script address not found: $keys_dir/multi-sig/script.addr" + echo "Please run scripts/multi-sig/generate-keys-and-script.sh first" + exit 1 +fi + +if [ ! -f "$keys_dir/multi-sig/script.json" ]; then + echo "Error: Multi-sig script JSON not found: $keys_dir/multi-sig/script.json" + exit 1 +fi + +if [ ! -f "$keys_dir/payment.addr" ]; then + echo "Error: Payment address file not found: $keys_dir/payment.addr" + echo "Please run scripts/generate-keys.sh first" + exit 1 +fi + +if [ ! -f "$keys_dir/stake.vkey" ]; then + echo "Error: Stake verification key not found: $keys_dir/stake.vkey" + exit 1 +fi + +for i in 1 2 3; do + if [ ! -f "$keys_dir/multi-sig/$i.skey" ]; then + echo "Error: Multi-sig signing key $i not found: $keys_dir/multi-sig/$i.skey" + exit 1 + fi + if [ ! -f "$keys_dir/multi-sig/$i.keyhash" ]; then + echo "Error: Multi-sig keyhash $i not found: $keys_dir/multi-sig/$i.keyhash" + exit 1 + fi +done + +if [ ! -f "$keys_dir/payment.skey" ]; then + echo "Error: Payment signing key not found: $keys_dir/payment.skey" + exit 1 +fi # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" @@ -26,97 +67,131 @@ fi echo "Using running container: $container_name" +# Extract network from container name (format: node-network-version-container) +network=$(echo "$container_name" | cut -d'-' -f2) + # Function to execute cardano-cli commands inside the container container_cli() { - docker exec -ti $container_name cardano-cli "$@" + docker exec -ti "$container_name" cardano-cli "$@" +} + +# Helper function to get UTXO with validation +get_utxo() { + local address=$1 + local utxo_output + utxo_output=$(container_cli conway query utxo --address "$address" --out-file /dev/stdout) + local utxo + utxo=$(echo "$utxo_output" | jq -r 'keys[0]') + if [ -z "$utxo" ] || [ "$utxo" = "null" ]; then + echo "Error: No UTXO found at address: $address" >&2 + exit 1 + fi + echo "$utxo" } echo "\nPull the latest guardrails script." -curl --silent -J -L https://book.world.dev.cardano.org/environments/mainnet/guardrails-script.plutus -o $txs_dir/guardrails-script.plutus +# Use network-specific URL (mainnet uses world.dev, testnets use play.dev) +if [ "$network" = "mainnet" ]; then + guardrails_url="https://book.world.dev.cardano.org/environments/mainnet/guardrails-script.plutus" +else + guardrails_url="https://book.play.dev.cardano.org/environments/$network/guardrails-script.plutus" +fi +curl --silent -J -L "$guardrails_url" -o "$txs_dir/guardrails-script.plutus" + +# Check guardrails script was downloaded +if [ ! -f "$txs_dir/guardrails-script.plutus" ]; then + echo "Error: Failed to download guardrails script" + exit 1 +fi echo "\nGet the guardrails script hash from the genesis file." -SCRIPT_HASH=$(container_cli hash script --script-file $txs_dir/guardrails-script.plutus) +SCRIPT_HASH=$(container_cli hash script --script-file "$txs_dir/guardrails-script.plutus") echo "Script hash: $SCRIPT_HASH" # Building, signing and submitting an parameter update governance action echo "Creating and submitting protocol param update governance action, using the multi-sig's ada." -# Get the script's directory -script_dir=$(dirname "$0") - -# Get the container name from the get-container script -container_name="$("$script_dir/../helper/get-container.sh")" - -if [ -z "$container_name" ]; then - echo "Failed to determine a running container." - exit 1 -fi - -echo "Using running container: $container_name" - -# Function to execute cardano-cli commands inside the container -container_cli() { - docker exec -ti $container_name cardano-cli "$@" -} - container_cli conway governance action create-protocol-parameters-update \ --testnet \ - --governance-action-deposit $(container_cli conway query gov-state | jq -r '.currentPParams.govActionDeposit') \ - --deposit-return-stake-verification-key-file $keys_dir/stake.vkey \ + --governance-action-deposit "$(container_cli conway query gov-state | jq -r '.currentPParams.govActionDeposit')" \ + --deposit-return-stake-verification-key-file "$keys_dir/stake.vkey" \ --anchor-url "$METADATA_URL" \ --anchor-data-hash "$METADATA_HASH" \ --constitution-script-hash "$SCRIPT_HASH" \ --key-reg-deposit-amt 3000000 \ --out-file "$tx_cert_path" +# Check certificate file was created +if [ ! -f "$tx_cert_path" ]; then + echo "Error: Failed to create certificate file" + exit 1 +fi + echo "Building transaction" +script_addr=$(cat "$keys_dir/multi-sig/script.addr") +payment_addr=$(cat "$keys_dir/payment.addr") +script_utxo=$(get_utxo "$script_addr") +payment_utxo=$(get_utxo "$payment_addr") + container_cli conway transaction build \ - --tx-in "$(container_cli conway query utxo --address "$(cat $keys_dir/multi-sig/script.addr)" --out-file /dev/stdout | jq -r 'keys[0]')" \ - --tx-in-script-file $keys_dir/multi-sig/script.json \ - --tx-in "$(container_cli conway query utxo --address "$(cat $keys_dir/payment.addr)" --out-file /dev/stdout | jq -r 'keys[0]')" \ - --tx-in-collateral "$(container_cli conway query utxo --address "$(cat $keys_dir/payment.addr)" --out-file /dev/stdout | jq -r 'keys[0]')" \ - --change-address "$(cat $keys_dir/payment.addr)" \ + --tx-in "$script_utxo" \ + --tx-in-script-file "$keys_dir/multi-sig/script.json" \ + --tx-in "$payment_utxo" \ + --tx-in-collateral "$payment_utxo" \ + --change-address "$payment_addr" \ --proposal-file "$tx_cert_path" \ - --proposal-script-file $txs_dir/guardrails-script.plutus \ + --proposal-script-file "$txs_dir/guardrails-script.plutus" \ --proposal-redeemer-value {} \ - --required-signer-hash "$(cat $keys_dir/multi-sig/1.keyhash)" \ - --required-signer-hash "$(cat $keys_dir/multi-sig/2.keyhash)" \ - --required-signer-hash "$(cat $keys_dir/multi-sig/3.keyhash)" \ + --required-signer-hash "$(cat "$keys_dir/multi-sig/1.keyhash")" \ + --required-signer-hash "$(cat "$keys_dir/multi-sig/2.keyhash")" \ + --required-signer-hash "$(cat "$keys_dir/multi-sig/3.keyhash")" \ --out-file "$tx_unsigned_path" +# Check transaction file was created +if [ ! -f "$tx_unsigned_path" ]; then + echo "Error: Failed to create unsigned transaction file" + exit 1 +fi + # Create multisig witnesses container_cli conway transaction witness \ --tx-body-file "$tx_unsigned_path" \ - --signing-key-file $keys_dir/multi-sig/1.skey \ + --signing-key-file "$keys_dir/multi-sig/1.skey" \ --out-file "$tx_path_stub-1.witness" container_cli conway transaction witness \ --tx-body-file "$tx_unsigned_path" \ - --signing-key-file $keys_dir/multi-sig/2.skey \ + --signing-key-file "$keys_dir/multi-sig/2.skey" \ --out-file "$tx_path_stub-2.witness" container_cli conway transaction witness \ --tx-body-file "$tx_unsigned_path" \ - --signing-key-file $keys_dir/multi-sig/3.skey \ + --signing-key-file "$keys_dir/multi-sig/3.skey" \ --out-file "$tx_path_stub-3.witness" # Create witness container_cli conway transaction witness \ --tx-body-file "$tx_unsigned_path" \ - --signing-key-file $keys_dir/payment.skey \ + --signing-key-file "$keys_dir/payment.skey" \ --out-file "$tx_path_stub-payment.witness" # Assemble Transaction container_cli conway transaction assemble \ --tx-body-file "$tx_unsigned_path" \ --witness-file "$tx_path_stub-payment.witness" \ + --witness-file "$tx_path_stub-1.witness" \ --witness-file "$tx_path_stub-2.witness" \ --witness-file "$tx_path_stub-3.witness" \ - --witness-file "$tx_path_stub-3.witness" \ --out-file "$tx_signed_path" +# Check signed transaction file was created +if [ ! -f "$tx_signed_path" ]; then + echo "Error: Failed to create signed transaction file" + exit 1 +fi + # Submit the transaction echo "Submitting transaction" -container_cli conway transaction submit --tx-file $tx_signed_path +container_cli conway transaction submit --tx-file "$tx_signed_path" diff --git a/scripts/multi-sig/drep-metadata.sh b/scripts/multi-sig/drep-metadata.sh index d4ad862..d0674d1 100755 --- a/scripts/multi-sig/drep-metadata.sh +++ b/scripts/multi-sig/drep-metadata.sh @@ -1,15 +1,54 @@ #!/bin/bash +set -euo pipefail -# Define directory paths -keys_dir="./keys" -txs_dir="./txs/multi-sig" +# Get the script's directory and project root +script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" +txs_dir="$project_root/txs/multi-sig" tx_path_stub="$txs_dir/one-sig-drep-vote" tx_cert_path="$tx_path_stub-update.cert" tx_unsigned_path="$tx_path_stub.unsigned" tx_signed_path="$tx_path_stub.signed" -# Get the script's directory -script_dir=$(dirname "$0") +# Check required files exist +if [ ! -f "$keys_dir/payment.addr" ]; then + echo "Error: Payment address file not found: $keys_dir/payment.addr" + echo "Please run scripts/generate-keys.sh first" + exit 1 +fi + +if [ ! -f "$keys_dir/payment.skey" ]; then + echo "Error: Payment signing key not found: $keys_dir/payment.skey" + exit 1 +fi + +if [ ! -f "$keys_dir/multi-sig/1.skey" ]; then + echo "Error: Multi-sig signing key 1 not found: $keys_dir/multi-sig/1.skey" + exit 1 +fi + +if [ ! -f "$keys_dir/multi-sig/1.keyhash" ]; then + echo "Error: Multi-sig keyhash 1 not found: $keys_dir/multi-sig/1.keyhash" + exit 1 +fi + +if [ ! -f "$txs_dir/drep-one-sig.id" ]; then + echo "Error: DRep script ID not found: $txs_dir/drep-one-sig.id" + exit 1 +fi + +if [ ! -f "$txs_dir/drep-one-sig.json" ]; then + echo "Error: DRep script JSON not found: $txs_dir/drep-one-sig.json" + exit 1 +fi + +if [ ! -f "$txs_dir/metadata.json" ]; then + echo "Error: Metadata file not found: $txs_dir/metadata.json" + exit 1 +fi # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" @@ -23,37 +62,65 @@ echo "Using running container: $container_name" # Function to execute cardano-cli commands inside the container container_cli() { - docker exec -ti $container_name cardano-cli "$@" + docker exec -ti "$container_name" cardano-cli "$@" +} + +# Helper function to get UTXO with validation +get_utxo() { + local address=$1 + local utxo_output + utxo_output=$(container_cli conway query utxo --address "$address" --out-file /dev/stdout) + local utxo + utxo=$(echo "$utxo_output" | jq -r 'keys[0]') + if [ -z "$utxo" ] || [ "$utxo" = "null" ]; then + echo "Error: No UTXO found at address: $address" >&2 + exit 1 + fi + echo "$utxo" } echo "Building DRep Update Certificate" container_cli conway governance drep update-certificate \ - --drep-script-hash $(cat $txs_dir/drep-one-sig.id) \ - --out-file $tx_cert_path + --drep-script-hash "$(cat "$txs_dir/drep-one-sig.id")" \ + --out-file "$tx_cert_path" + +# Check certificate file was created +if [ ! -f "$tx_cert_path" ]; then + echo "Error: Failed to create certificate file" + exit 1 +fi echo "Building transaction" +payment_addr=$(cat "$keys_dir/payment.addr") +utxo=$(get_utxo "$payment_addr") container_cli conway transaction build \ - --tx-in $(container_cli conway query utxo --address $(cat $keys_dir/payment.addr) --out-file /dev/stdout | jq -r 'keys[0]') \ - --change-address $(cat $keys_dir/payment.addr) \ - --required-signer-hash "$(cat $keys_dir/multi-sig/1.keyhash)" \ - --certificate-file $tx_cert_path \ - --certificate-script-file $txs_dir/drep-one-sig.json \ - --metadata-json-file $txs_dir/metadata.json \ + --tx-in "$utxo" \ + --change-address "$payment_addr" \ + --required-signer-hash "$(cat "$keys_dir/multi-sig/1.keyhash")" \ + --certificate-file "$tx_cert_path" \ + --certificate-script-file "$txs_dir/drep-one-sig.json" \ + --metadata-json-file "$txs_dir/metadata.json" \ --out-file "$tx_unsigned_path" +# Check transaction file was created +if [ ! -f "$tx_unsigned_path" ]; then + echo "Error: Failed to create unsigned transaction file" + exit 1 +fi + # Create multisig witnesses container_cli conway transaction witness \ --tx-body-file "$tx_unsigned_path" \ - --signing-key-file $keys_dir/multi-sig/1.skey \ + --signing-key-file "$keys_dir/multi-sig/1.skey" \ --out-file "$tx_path_stub-1.witness" # Create witness container_cli conway transaction witness \ --tx-body-file "$tx_unsigned_path" \ - --signing-key-file $keys_dir/payment.skey \ + --signing-key-file "$keys_dir/payment.skey" \ --out-file "$tx_path_stub-payment.witness" # Assemble Transaction @@ -63,7 +130,13 @@ container_cli conway transaction assemble \ --witness-file "$tx_path_stub-1.witness" \ --out-file "$tx_signed_path" +# Check signed transaction file was created +if [ ! -f "$tx_signed_path" ]; then + echo "Error: Failed to create signed transaction file" + exit 1 +fi + # Submit the transaction echo "Submitting transaction" -container_cli conway transaction submit --tx-file $tx_signed_path +container_cli conway transaction submit --tx-file "$tx_signed_path" diff --git a/scripts/multi-sig/generate-keys-and-script.sh b/scripts/multi-sig/generate-keys-and-script.sh index 45a33dc..2eacbc8 100755 --- a/scripts/multi-sig/generate-keys-and-script.sh +++ b/scripts/multi-sig/generate-keys-and-script.sh @@ -1,10 +1,19 @@ #!/bin/bash +set -euo pipefail -# Define directories -keys_dir="./keys" - -# Get the script's directory +# Get the script's directory and project root script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" +scripts_dir="$project_root/scripts" + +# Check required template file exists +if [ ! -f "$scripts_dir/multi-sig/multi-sig-template.json" ]; then + echo "Error: Multi-sig template file not found: $scripts_dir/multi-sig/multi-sig-template.json" + exit 1 +fi # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" @@ -18,55 +27,55 @@ echo "Using running container: $container_name" # Function to execute cardano-cli commands inside the container container_cli() { - docker exec -ti $container_name cardano-cli "$@" + docker exec -ti "$container_name" cardano-cli "$@" } echo "Creating three keys to control a multi-sig script." # Create directory for keys -mkdir -p $keys_dir/multi-sig +mkdir -p "$keys_dir/multi-sig" # Key 1 container_cli address key-gen \ - --verification-key-file keys/multi-sig/1.vkey \ - --signing-key-file keys/multi-sig/1.skey + --verification-key-file "$keys_dir/multi-sig/1.vkey" \ + --signing-key-file "$keys_dir/multi-sig/1.skey" container_cli address key-hash \ - --payment-verification-key-file keys/multi-sig/1.vkey > keys/multi-sig/1.keyhash + --payment-verification-key-file "$keys_dir/multi-sig/1.vkey" > "$keys_dir/multi-sig/1.keyhash" # Key 2 container_cli address key-gen \ - --verification-key-file keys/multi-sig/2.vkey \ - --signing-key-file keys/multi-sig/2.skey + --verification-key-file "$keys_dir/multi-sig/2.vkey" \ + --signing-key-file "$keys_dir/multi-sig/2.skey" container_cli address key-hash \ - --payment-verification-key-file keys/multi-sig/2.vkey > keys/multi-sig/2.keyhash + --payment-verification-key-file "$keys_dir/multi-sig/2.vkey" > "$keys_dir/multi-sig/2.keyhash" # Key 3 container_cli address key-gen \ - --verification-key-file keys/multi-sig/3.vkey \ - --signing-key-file keys/multi-sig/3.skey + --verification-key-file "$keys_dir/multi-sig/3.vkey" \ + --signing-key-file "$keys_dir/multi-sig/3.skey" container_cli address key-hash \ - --payment-verification-key-file keys/multi-sig/3.vkey > keys/multi-sig/3.keyhash + --payment-verification-key-file "$keys_dir/multi-sig/3.vkey" > "$keys_dir/multi-sig/3.keyhash" echo "Copying the script template." -cp ./scripts/multi-sig/multi-sig-template.json $keys_dir/multi-sig/script.json +cp "$scripts_dir/multi-sig/multi-sig-template.json" "$keys_dir/multi-sig/script.json" echo "Adding keys to script." # Remove \r from the key hashes when reading them -jq --arg kh1 "$(tr -d '\r' < $keys_dir/multi-sig/1.keyhash)" \ - --arg kh2 "$(tr -d '\r' < $keys_dir/multi-sig/2.keyhash)" \ - --arg kh3 "$(tr -d '\r' < $keys_dir/multi-sig/3.keyhash)" \ +jq --arg kh1 "$(tr -d '\r' < "$keys_dir/multi-sig/1.keyhash")" \ + --arg kh2 "$(tr -d '\r' < "$keys_dir/multi-sig/2.keyhash")" \ + --arg kh3 "$(tr -d '\r' < "$keys_dir/multi-sig/3.keyhash")" \ '.scripts[0].keyHash = $kh1 | .scripts[1].keyHash = $kh2 | .scripts[2].keyHash = $kh3' \ "$keys_dir/multi-sig/script.json" > temp.json && mv temp.json "$keys_dir/multi-sig/script.json" echo "Creating script address." -cardano-cli address build \ - --payment-script-file $keys_dir/multi-sig/script.json \ - --out-file $keys_dir/multi-sig/script.addr +container_cli address build \ + --payment-script-file "$keys_dir/multi-sig/script.json" \ + --out-file "$keys_dir/multi-sig/script.addr" echo "Done!" \ No newline at end of file diff --git a/scripts/multi-sig/query-multisig.sh b/scripts/multi-sig/query-multisig.sh index 2b870a1..b42e6e3 100755 --- a/scripts/multi-sig/query-multisig.sh +++ b/scripts/multi-sig/query-multisig.sh @@ -1,10 +1,19 @@ #!/bin/bash +set -euo pipefail -# Define directories -keys_dir="./keys" - -# Get the script's directory +# Get the script's directory and project root script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" + +# Check required files exist +if [ ! -f "$keys_dir/multi-sig/script.addr" ]; then + echo "Error: Multi-sig script address not found: $keys_dir/multi-sig/script.addr" + echo "Please run scripts/multi-sig/generate-keys-and-script.sh first" + exit 1 +fi # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" @@ -18,12 +27,13 @@ echo "Using running container: $container_name" # Function to execute cardano-cli commands inside the container container_cli() { - docker exec -ti $container_name cardano-cli "$@" + docker exec -ti "$container_name" cardano-cli "$@" } -echo "Querying UTXOs for your multisig script address: $(cat $keys_dir/multi-sig/script.addr)" +script_addr=$(cat "$keys_dir/multi-sig/script.addr") +echo "Querying UTXOs for your multisig script address: $script_addr" # Query the UTxOs controlled by multisig script address container_cli conway query utxo \ - --address "$(cat $keys_dir/multi-sig/script.addr)" \ - --out-file /dev/stdout \ No newline at end of file + --address "$script_addr" \ + --out-file /dev/stdout \ No newline at end of file diff --git a/scripts/multi-sig/send-ada-from-script.sh b/scripts/multi-sig/send-ada-from-script.sh index 27deb38..de884fa 100755 --- a/scripts/multi-sig/send-ada-from-script.sh +++ b/scripts/multi-sig/send-ada-from-script.sh @@ -1,18 +1,54 @@ #!/bin/bash +set -euo pipefail # ~~~~~~~~~~~~ CHANGE THIS ~~~~~~~~~~~~ LOVELACE_AMOUNT=1000000 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Define directory paths -keys_dir="./keys" -txs_dir="./txs/multi-sig" +# Get the script's directory and project root +script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" +txs_dir="$project_root/txs/multi-sig" tx_path_stub="$txs_dir/send-ada-from-script" tx_unsigned_path="$tx_path_stub.unsigned" tx_signed_path="$tx_path_stub.signed" -# Get the script's directory -script_dir=$(dirname "$0") +# Check required files exist +if [ ! -f "$keys_dir/multi-sig/script.addr" ]; then + echo "Error: Multi-sig script address not found: $keys_dir/multi-sig/script.addr" + echo "Please run scripts/multi-sig/generate-keys-and-script.sh first" + exit 1 +fi + +if [ ! -f "$keys_dir/multi-sig/script.json" ]; then + echo "Error: Multi-sig script JSON not found: $keys_dir/multi-sig/script.json" + exit 1 +fi + +if [ ! -f "$keys_dir/payment.addr" ]; then + echo "Error: Payment address file not found: $keys_dir/payment.addr" + echo "Please run scripts/generate-keys.sh first" + exit 1 +fi + +for i in 1 2 3; do + if [ ! -f "$keys_dir/multi-sig/$i.skey" ]; then + echo "Error: Multi-sig signing key $i not found: $keys_dir/multi-sig/$i.skey" + exit 1 + fi + if [ ! -f "$keys_dir/multi-sig/$i.keyhash" ]; then + echo "Error: Multi-sig keyhash $i not found: $keys_dir/multi-sig/$i.keyhash" + exit 1 + fi +done + +if [ ! -f "$keys_dir/payment.skey" ]; then + echo "Error: Payment signing key not found: $keys_dir/payment.skey" + exit 1 +fi # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" @@ -26,7 +62,21 @@ echo "Using running container: $container_name" # Function to execute cardano-cli commands inside the container container_cli() { - docker exec -ti $container_name cardano-cli "$@" + docker exec -ti "$container_name" cardano-cli "$@" +} + +# Helper function to get UTXO with validation +get_utxo() { + local address=$1 + local utxo_output + utxo_output=$(container_cli conway query utxo --address "$address" --out-file /dev/stdout) + local utxo + utxo=$(echo "$utxo_output" | jq -r 'keys[0]') + if [ -z "$utxo" ] || [ "$utxo" = "null" ]; then + echo "Error: No UTXO found at address: $address" >&2 + exit 1 + fi + echo "$utxo" } # Send ada to the multisig payment script @@ -34,48 +84,64 @@ echo "Sending $LOVELACE_AMOUNT lovelace to the payment address from the script." echo "Building transaction" +script_addr=$(cat "$keys_dir/multi-sig/script.addr") +payment_addr=$(cat "$keys_dir/payment.addr") +script_utxo=$(get_utxo "$script_addr") + container_cli conway transaction build \ - --tx-in $(container_cli conway query utxo --address $(cat $keys_dir/multi-sig/script.addr) --out-file /dev/stdout | jq -r 'keys[0]') \ - --tx-in-script-file $keys_dir/multi-sig/script.json \ - --tx-out $(cat $keys_dir/payment.addr)+$LOVELACE_AMOUNT \ - --change-address $(cat $keys_dir/multi-sig/script.addr) \ - --required-signer-hash "$(cat $keys_dir/multi-sig/1.keyhash)" \ - --required-signer-hash "$(cat $keys_dir/multi-sig/2.keyhash)" \ - --required-signer-hash "$(cat $keys_dir/multi-sig/3.keyhash)" \ - --out-file "$txs_unsigned_path" + --tx-in "$script_utxo" \ + --tx-in-script-file "$keys_dir/multi-sig/script.json" \ + --tx-out "$payment_addr+$LOVELACE_AMOUNT" \ + --change-address "$script_addr" \ + --required-signer-hash "$(cat "$keys_dir/multi-sig/1.keyhash")" \ + --required-signer-hash "$(cat "$keys_dir/multi-sig/2.keyhash")" \ + --required-signer-hash "$(cat "$keys_dir/multi-sig/3.keyhash")" \ + --out-file "$tx_unsigned_path" + +# Check transaction file was created +if [ ! -f "$tx_unsigned_path" ]; then + echo "Error: Failed to create unsigned transaction file" + exit 1 +fi # Create multisig witnesses container_cli conway transaction witness \ --tx-body-file "$tx_unsigned_path" \ - --signing-key-file $keys_dir/multi-sig/1.skey \ + --signing-key-file "$keys_dir/multi-sig/1.skey" \ --out-file "$tx_path_stub-1.witness" container_cli conway transaction witness \ --tx-body-file "$tx_unsigned_path" \ - --signing-key-file $keys_dir/multi-sig/2.skey \ + --signing-key-file "$keys_dir/multi-sig/2.skey" \ --out-file "$tx_path_stub-2.witness" container_cli conway transaction witness \ --tx-body-file "$tx_unsigned_path" \ - --signing-key-file $keys_dir/multi-sig/3.skey \ + --signing-key-file "$keys_dir/multi-sig/3.skey" \ --out-file "$tx_path_stub-3.witness" # Create witness container_cli conway transaction witness \ --tx-body-file "$tx_unsigned_path" \ - --signing-key-file $keys_dir/payment.skey \ + --signing-key-file "$keys_dir/payment.skey" \ --out-file "$tx_path_stub-payment.witness" # Assemble Transaction container_cli conway transaction assemble \ --tx-body-file "$tx_unsigned_path" \ --witness-file "$tx_path_stub-payment.witness" \ + --witness-file "$tx_path_stub-1.witness" \ --witness-file "$tx_path_stub-2.witness" \ --witness-file "$tx_path_stub-3.witness" \ - --witness-file "$tx_path_stub-3.witness" \ --out-file "$tx_signed_path" +# Check signed transaction file was created +if [ ! -f "$tx_signed_path" ]; then + echo "Error: Failed to create signed transaction file" + exit 1 +fi + # Submit the transaction echo "Submitting transaction" -container_cli conway transaction submit --tx-file $tx_signed_path +container_cli conway transaction submit --tx-file "$tx_signed_path" diff --git a/scripts/multi-sig/send-ada-to-script.sh b/scripts/multi-sig/send-ada-to-script.sh index d2851a0..4966eb0 100755 --- a/scripts/multi-sig/send-ada-to-script.sh +++ b/scripts/multi-sig/send-ada-to-script.sh @@ -1,18 +1,38 @@ #!/bin/bash +set -euo pipefail # ~~~~~~~~~~~~ CHANGE THIS ~~~~~~~~~~~~ LOVELACE_AMOUNT=10000000 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Define directory paths -keys_dir="./keys" -txs_dir="./txs/multi-sig" +# Get the script's directory and project root +script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" +txs_dir="$project_root/txs/multi-sig" tx_path_stub="$txs_dir/send-ada-to-script" tx_unsigned_path="$tx_path_stub.unsigned" tx_signed_path="$tx_path_stub.signed" -# Get the script's directory -script_dir=$(dirname "$0") +# Check required files exist +if [ ! -f "$keys_dir/payment.addr" ]; then + echo "Error: Payment address file not found: $keys_dir/payment.addr" + echo "Please run scripts/generate-keys.sh first" + exit 1 +fi + +if [ ! -f "$keys_dir/payment.skey" ]; then + echo "Error: Payment signing key not found: $keys_dir/payment.skey" + exit 1 +fi + +if [ ! -f "$keys_dir/multi-sig/script.addr" ]; then + echo "Error: Multi-sig script address not found: $keys_dir/multi-sig/script.addr" + echo "Please run scripts/multi-sig/generate-keys-and-script.sh first" + exit 1 +fi # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" @@ -26,7 +46,21 @@ echo "Using running container: $container_name" # Function to execute cardano-cli commands inside the container container_cli() { - docker exec -ti $container_name cardano-cli "$@" + docker exec -ti "$container_name" cardano-cli "$@" +} + +# Helper function to get UTXO with validation +get_utxo() { + local address=$1 + local utxo_output + utxo_output=$(container_cli conway query utxo --address "$address" --out-file /dev/stdout) + local utxo + utxo=$(echo "$utxo_output" | jq -r 'keys[0]') + if [ -z "$utxo" ] || [ "$utxo" = "null" ]; then + echo "Error: No UTXO found at address: $address" >&2 + exit 1 + fi + echo "$utxo" } # Send ada to the multisig payment script @@ -34,18 +68,34 @@ echo "Sending $LOVELACE_AMOUNT lovelace to the multisig payment address." echo "Building transaction" +payment_addr=$(cat "$keys_dir/payment.addr") +script_addr=$(cat "$keys_dir/multi-sig/script.addr") +utxo=$(get_utxo "$payment_addr") + container_cli conway transaction build \ - --tx-in $(container_cli conway query utxo --address $(cat $keys_dir/payment.addr) --out-file /dev/stdout | jq -r 'keys[0]') \ - --tx-out $(cat $keys_dir/multi-sig/script.addr)+$LOVELACE_AMOUNT \ - --change-address $(cat $keys_dir/payment.addr) \ + --tx-in "$utxo" \ + --tx-out "$script_addr+$LOVELACE_AMOUNT" \ + --change-address "$payment_addr" \ --out-file "$tx_unsigned_path" +# Check transaction file was created +if [ ! -f "$tx_unsigned_path" ]; then + echo "Error: Failed to create unsigned transaction file" + exit 1 +fi + container_cli conway transaction sign \ --tx-body-file "$tx_unsigned_path" \ - --signing-key-file $keys_dir/payment.skey \ + --signing-key-file "$keys_dir/payment.skey" \ --out-file "$tx_signed_path" +# Check signed transaction file was created +if [ ! -f "$tx_signed_path" ]; then + echo "Error: Failed to create signed transaction file" + exit 1 +fi + # Submit the transaction echo "Submitting transaction" -container_cli conway transaction submit --tx-file $tx_signed_path +container_cli conway transaction submit --tx-file "$tx_signed_path" diff --git a/scripts/multi-sig/stake-multisig.sh b/scripts/multi-sig/stake-multisig.sh index 911959f..8e8ce14 100755 --- a/scripts/multi-sig/stake-multisig.sh +++ b/scripts/multi-sig/stake-multisig.sh @@ -1,15 +1,44 @@ #!/bin/bash +set -euo pipefail -# Define directory paths -keys_dir="./keys" -txs_dir="./txs/multi-sig" +# Get the script's directory and project root +script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" +txs_dir="$project_root/txs/multi-sig" tx_path_stub="$txs_dir/stake-reg" tx_cert_path="$tx_path_stub.cert" tx_unsigned_path="$tx_path_stub.unsigned" tx_signed_path="$tx_path_stub.signed" -# Get the script's directory -script_dir=$(dirname "$0") +# Check required files exist +if [ ! -f "$keys_dir/payment.addr" ]; then + echo "Error: Payment address file not found: $keys_dir/payment.addr" + echo "Please run scripts/generate-keys.sh first" + exit 1 +fi + +if [ ! -f "$keys_dir/payment.skey" ]; then + echo "Error: Payment signing key not found: $keys_dir/payment.skey" + exit 1 +fi + +if [ ! -f "$keys_dir/multi-sig/1.skey" ]; then + echo "Error: Multi-sig signing key 1 not found: $keys_dir/multi-sig/1.skey" + exit 1 +fi + +if [ ! -f "$keys_dir/multi-sig/1.keyhash" ]; then + echo "Error: Multi-sig keyhash 1 not found: $keys_dir/multi-sig/1.keyhash" + exit 1 +fi + +if [ ! -f "$txs_dir/drep-one-sig.json" ]; then + echo "Error: DRep script JSON not found: $txs_dir/drep-one-sig.json" + exit 1 +fi # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" @@ -23,36 +52,65 @@ echo "Using running container: $container_name" # Function to execute cardano-cli commands inside the container container_cli() { - docker exec -ti $container_name cardano-cli "$@" + docker exec -ti "$container_name" cardano-cli "$@" +} + +# Helper function to get UTXO with validation +get_utxo() { + local address=$1 + local utxo_output + utxo_output=$(container_cli conway query utxo --address "$address" --out-file /dev/stdout) + local utxo + utxo=$(echo "$utxo_output" | jq -r 'keys[0]') + if [ -z "$utxo" ] || [ "$utxo" = "null" ]; then + echo "Error: No UTXO found at address: $address" >&2 + exit 1 + fi + echo "$utxo" } echo "Registering your multi-sig as a stake credential." container_cli conway stake-address registration-certificate \ - --stake-script-file $txs_dir/drep-one-sig.json \ - --key-reg-deposit-amt "$(container_cli conway query gov-state | jq -r .currentPParams.stakeAddressDeposit)" \ + --stake-script-file "$txs_dir/drep-one-sig.json" \ + --key-reg-deposit-amt "$(container_cli conway query gov-state | jq -r '.currentPParams.stakeAddressDeposit')" \ --out-file "$tx_cert_path" +# Check certificate file was created +if [ ! -f "$tx_cert_path" ]; then + echo "Error: Failed to create certificate file" + exit 1 +fi + echo "Building transaction" +payment_addr=$(cat "$keys_dir/payment.addr") +utxo=$(get_utxo "$payment_addr") + container_cli conway transaction build \ - --tx-in $(container_cli conway query utxo --address $(cat $keys_dir/payment.addr) --out-file /dev/stdout | jq -r 'keys[0]') \ - --change-address $(cat $keys_dir/payment.addr) \ - --required-signer-hash "$(cat $keys_dir/multi-sig/1.keyhash)" \ - --certificate-file $tx_cert_path \ - --certificate-script-file $txs_dir/drep-one-sig.json \ + --tx-in "$utxo" \ + --change-address "$payment_addr" \ + --required-signer-hash "$(cat "$keys_dir/multi-sig/1.keyhash")" \ + --certificate-file "$tx_cert_path" \ + --certificate-script-file "$txs_dir/drep-one-sig.json" \ --out-file "$tx_unsigned_path" +# Check transaction file was created +if [ ! -f "$tx_unsigned_path" ]; then + echo "Error: Failed to create unsigned transaction file" + exit 1 +fi + # Create multisig witnesses container_cli conway transaction witness \ --tx-body-file "$tx_unsigned_path" \ - --signing-key-file $keys_dir/multi-sig/1.skey \ + --signing-key-file "$keys_dir/multi-sig/1.skey" \ --out-file "$tx_path_stub-1.witness" # Create witness container_cli conway transaction witness \ --tx-body-file "$tx_unsigned_path" \ - --signing-key-file $keys_dir/payment.skey \ + --signing-key-file "$keys_dir/payment.skey" \ --out-file "$tx_path_stub-payment.witness" # Assemble Transaction @@ -62,7 +120,13 @@ container_cli conway transaction assemble \ --witness-file "$tx_path_stub-1.witness" \ --out-file "$tx_signed_path" +# Check signed transaction file was created +if [ ! -f "$tx_signed_path" ]; then + echo "Error: Failed to create signed transaction file" + exit 1 +fi + # Submit the transaction echo "Submitting transaction" -container_cli conway transaction submit --tx-file $tx_signed_path +container_cli conway transaction submit --tx-file "$tx_signed_path" diff --git a/scripts/query/dump-node-state.sh b/scripts/query/dump-node-state.sh index ee2789e..a783f82 100755 --- a/scripts/query/dump-node-state.sh +++ b/scripts/query/dump-node-state.sh @@ -1,7 +1,12 @@ #!/bin/bash +set -euo pipefail -# Get the script's directory +# Get the script's directory and project root script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/.." && pwd) + +# Define directory paths relative to project root +dumps_dir="$project_root/dumps" # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" @@ -15,55 +20,58 @@ echo "Using running container: $container_name" # Function to execute cardano-cli commands inside the container container_cli() { - docker exec -ti $container_name cardano-cli "$@" + docker exec -ti "$container_name" cardano-cli "$@" } -# Get the network name +# Get the network name # Split the container name and extract the second part -network=$(echo $container_name | cut -d'-' -f2) +network=$(echo "$container_name" | cut -d'-' -f2) + +# Create dumps directory if it doesn't exist +mkdir -p "$dumps_dir/$network" # Dumping out CC state echo "Dumping constitutional committee state." -container_cli conway query committee-state > ./dumps/$network/committee.json +container_cli conway query committee-state > "$dumps_dir/$network/committee.json" # Dumping out constitution state echo "Dumping constitution state." -container_cli conway query constitution > ./dumps/$network/constitution.json +container_cli conway query constitution > "$dumps_dir/$network/constitution.json" # Query DReps from ledger state echo "Dumping DReps from ledger state." container_cli conway query drep-state \ - --all-dreps > ./dumps/$network/dreps-info.json + --all-dreps > "$dumps_dir/$network/dreps-info.json" container_cli conway query drep-stake-distribution \ - --all-dreps > ./dumps/$network/dreps-power.json + --all-dreps > "$dumps_dir/$network/dreps-power.json" # Dumping governance ledger state echo "Dumping whole governance state from ledger state." -container_cli conway query gov-state > ./dumps/$network/gov-state.json +container_cli conway query gov-state > "$dumps_dir/$network/gov-state.json" # Dumping proposals stored in ledger state echo "Dumping governance actions from ledger state." -container_cli conway query gov-state | jq -r '.proposals' > ./dumps/$network/governance-actions.json +container_cli conway query gov-state | jq -r '.proposals' > "$dumps_dir/$network/governance-actions.json" # Dumping out parameters state echo "Dumping protocol parameters state." -container_cli conway query protocol-parameters > ./dumps/$network/params.json +container_cli conway query protocol-parameters > "$dumps_dir/$network/params.json" # Dumping out SPO state echo "Dumping SPO stake distribution state." container_cli conway query spo-stake-distribution \ - --all-spos > ./dumps/$network/spo-stake.json + --all-spos > "$dumps_dir/$network/spo-stake.json" # Dumping out SPO state echo "Dumping treasury state." -container_cli conway query treasury > ./dumps/$network/treasury.json \ No newline at end of file +container_cli conway query treasury > "$dumps_dir/$network/treasury.json" \ No newline at end of file diff --git a/scripts/query/own-utxos.sh b/scripts/query/own-utxos.sh index c99a9fe..1c9bb36 100755 --- a/scripts/query/own-utxos.sh +++ b/scripts/query/own-utxos.sh @@ -1,10 +1,19 @@ #!/bin/bash +set -euo pipefail -# Define directories -keys_dir="./keys" - -# Get the script's directory +# Get the script's directory and project root script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" + +# Check if you have a address created +if [ ! -f "$keys_dir/payment.addr" ]; then + echo "Please generate some keys and addresses before querying funds." + echo "Exiting." + exit 0 +fi # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" @@ -18,19 +27,13 @@ echo "Using running container: $container_name" # Function to execute cardano-cli commands inside the container container_cli() { - docker exec -ti $container_name cardano-cli "$@" + docker exec -ti "$container_name" cardano-cli "$@" } -# Check if you have a address created -if [ ! -f "$keys_dir/payment.addr" ]; then - echo "Please generate some keys and addresses before querying funds." - echo "Exiting." - exit 0 -fi - -echo "Querying UTXOs for your address: $(cat $keys_dir/payment.addr)" +payment_addr=$(cat "$keys_dir/payment.addr") +echo "Querying UTXOs for your address: $payment_addr" # Query the UTxOs controlled by the payment address container_cli conway query utxo \ - --address "$(cat $keys_dir/payment.addr)" \ - --out-file /dev/stdout \ No newline at end of file + --address "$payment_addr" \ + --out-file /dev/stdout \ No newline at end of file diff --git a/scripts/query/stake-info.sh b/scripts/query/stake-info.sh index 350858e..36f93e0 100755 --- a/scripts/query/stake-info.sh +++ b/scripts/query/stake-info.sh @@ -1,10 +1,25 @@ #!/bin/bash +set -euo pipefail -# Define directories -keys_dir="./keys" - -# Get the script's directory +# Get the script's directory and project root script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" + +# Check if you have a address created +if [ ! -f "$keys_dir/payment.addr" ]; then + echo "Please generate some keys and addresses before querying funds." + echo "Exiting." + exit 0 +fi + +if [ ! -f "$keys_dir/stake.addr" ]; then + echo "Error: Stake address file not found: $keys_dir/stake.addr" + echo "Please run scripts/generate-keys.sh first" + exit 1 +fi # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" @@ -18,18 +33,12 @@ echo "Using running container: $container_name" # Function to execute cardano-cli commands inside the container container_cli() { - docker exec -ti $container_name cardano-cli "$@" + docker exec -ti "$container_name" cardano-cli "$@" } -# Check if you have a address created -if [ ! -f "$keys_dir/payment.addr" ]; then - echo "Please generate some keys and addresses before querying funds." - echo "Exiting." - exit 0 -fi - -echo "Querying Stake Account info for your address: $(cat $keys_dir/stake.addr)" +stake_addr=$(cat "$keys_dir/stake.addr") +echo "Querying Stake Account info for your address: $stake_addr" container_cli conway query stake-address-info \ - --address "$(cat $keys_dir/stake.addr)" \ - --out-file /dev/stdout + --address "$stake_addr" \ + --out-file /dev/stdout diff --git a/scripts/query/stake-pools.sh b/scripts/query/stake-pools.sh index 0608776..d56fb26 100755 --- a/scripts/query/stake-pools.sh +++ b/scripts/query/stake-pools.sh @@ -1,4 +1,5 @@ #!/bin/bash +set -euo pipefail # Get the script's directory script_dir=$(dirname "$0") @@ -15,7 +16,7 @@ echo "Using running container: $container_name" # Function to execute cardano-cli commands inside the container container_cli() { - docker exec -ti $container_name cardano-cli "$@" + docker exec -ti "$container_name" cardano-cli "$@" } # Query the stake pools diff --git a/scripts/query/tip.sh b/scripts/query/tip.sh index 4e1ff2e..287a9f8 100755 --- a/scripts/query/tip.sh +++ b/scripts/query/tip.sh @@ -1,4 +1,5 @@ #!/bin/bash +set -euo pipefail # Get the script's directory script_dir=$(dirname "$0") @@ -15,7 +16,7 @@ echo "Using running container: $container_name" # Function to execute cardano-cli commands inside the container container_cli() { - docker exec -ti $container_name cardano-cli "$@" + docker exec -ti "$container_name" cardano-cli "$@" } # Query the tip of the blockchain as observed by the node diff --git a/scripts/query/utxos-for-address.sh b/scripts/query/utxos-for-address.sh index 27516bc..04e0f56 100755 --- a/scripts/query/utxos-for-address.sh +++ b/scripts/query/utxos-for-address.sh @@ -1,15 +1,16 @@ #!/bin/bash - +set -euo pipefail # ~~~~~~~~~~~~ CHANGE THIS ~~~~~~~~~~~~ ADDRESS="addr_test1wz0vzkrzked85ywpsq4ffmx2etvjtnk07lvldrp3d4ht86ckfg639" # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Define directories -keys_dir="./keys" - -# Get the script's directory +# Get the script's directory and project root script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" @@ -23,7 +24,7 @@ echo "Using running container: $container_name" # Function to execute cardano-cli commands inside the container container_cli() { - docker exec -ti $container_name cardano-cli "$@" + docker exec -ti "$container_name" cardano-cli "$@" } echo "Querying UTXOs for address: $ADDRESS" @@ -31,4 +32,4 @@ echo "Querying UTXOs for address: $ADDRESS" # Query the UTxOs controlled by the payment address container_cli conway query utxo \ --address "$ADDRESS" \ - --out-file /dev/stdout \ No newline at end of file + --out-file /dev/stdout \ No newline at end of file diff --git a/scripts/simple/metadata-tx.sh b/scripts/simple/metadata-tx.sh index 0c3e29e..97b17b8 100755 --- a/scripts/simple/metadata-tx.sh +++ b/scripts/simple/metadata-tx.sh @@ -1,18 +1,37 @@ #!/bin/bash +set -euo pipefail # ~~~~~~~~~~~~ CHANGE THIS ~~~~~~~~~~~~ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Define directory paths -keys_dir="./keys" -txs_dir="./txs" +# Get the script's directory and project root +script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" +txs_dir="$project_root/txs/simple" tx_path_stub="$txs_dir/metadata-transaction" tx_unsigned_path="$tx_path_stub.unsigned" tx_signed_path="$tx_path_stub.signed" -# Get the script's directory -script_dir=$(dirname "$0") +# Check required files exist +if [ ! -f "$keys_dir/payment.addr" ]; then + echo "Error: Payment address file not found: $keys_dir/payment.addr" + echo "Please run scripts/generate-keys.sh first" + exit 1 +fi + +if [ ! -f "$keys_dir/payment.skey" ]; then + echo "Error: Payment signing key not found: $keys_dir/payment.skey" + exit 1 +fi + +if [ ! -f "$txs_dir/metadata.json" ]; then + echo "Error: Metadata file not found: $txs_dir/metadata.json" + exit 1 +fi # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" @@ -26,23 +45,52 @@ echo "Using running container: $container_name" # Function to execute cardano-cli commands inside the container container_cli() { - docker exec -ti $container_name cardano-cli "$@" + docker exec -ti "$container_name" cardano-cli "$@" +} + +# Helper function to get UTXO with validation +get_utxo() { + local address=$1 + local utxo_output + utxo_output=$(container_cli conway query utxo --address "$address" --out-file /dev/stdout) + local utxo + utxo=$(echo "$utxo_output" | jq -r 'keys[0]') + if [ -z "$utxo" ] || [ "$utxo" = "null" ]; then + echo "Error: No UTXO found at address: $address" >&2 + exit 1 + fi + echo "$utxo" } echo "Building transaction" +payment_addr=$(cat "$keys_dir/payment.addr") +utxo=$(get_utxo "$payment_addr") + container_cli conway transaction build \ - --tx-in $(container_cli conway query utxo --address $(cat $keys_dir/payment.addr) --out-file /dev/stdout | jq -r 'keys[0]') \ - --change-address $(cat $keys_dir/payment.addr) \ + --tx-in "$utxo" \ + --change-address "$payment_addr" \ --metadata-json-file "$txs_dir/metadata.json" \ --out-file "$tx_unsigned_path" +# Check transaction file was created +if [ ! -f "$tx_unsigned_path" ]; then + echo "Error: Failed to create unsigned transaction file" + exit 1 +fi + container_cli conway transaction sign \ --tx-body-file "$tx_unsigned_path" \ - --signing-key-file $keys_dir/payment.skey \ + --signing-key-file "$keys_dir/payment.skey" \ --out-file "$tx_signed_path" +# Check signed transaction file was created +if [ ! -f "$tx_signed_path" ]; then + echo "Error: Failed to create signed transaction file" + exit 1 +fi + # Submit the transaction echo "Submitting transaction" -container_cli conway transaction submit --tx-file $tx_signed_path +container_cli conway transaction submit --tx-file "$tx_signed_path" diff --git a/scripts/simple/send-ada.sh b/scripts/simple/send-ada.sh index 2ca1683..5eb11d9 100755 --- a/scripts/simple/send-ada.sh +++ b/scripts/simple/send-ada.sh @@ -1,19 +1,33 @@ #!/bin/bash +set -euo pipefail # ~~~~~~~~~~~~ CHANGE THIS ~~~~~~~~~~~~ LOVELACE_AMOUNT=10000000 ADDRESS="addr_test1wqft2yqkp8wj5k5k7dy9725kxkcd4ep4ycp5uczuqtt3vqcgh63dt" # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Define directory paths -keys_dir="./keys" -txs_dir="./txs" +# Get the script's directory and project root +script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" +txs_dir="$project_root/txs/simple" tx_path_stub="$txs_dir/send-ada" tx_unsigned_path="$tx_path_stub.unsigned" tx_signed_path="$tx_path_stub.signed" -# Get the script's directory -script_dir=$(dirname "$0") +# Check required files exist +if [ ! -f "$keys_dir/payment.addr" ]; then + echo "Error: Payment address file not found: $keys_dir/payment.addr" + echo "Please run scripts/generate-keys.sh first" + exit 1 +fi + +if [ ! -f "$keys_dir/payment.skey" ]; then + echo "Error: Payment signing key not found: $keys_dir/payment.skey" + exit 1 +fi # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" @@ -27,26 +41,55 @@ echo "Using running container: $container_name" # Function to execute cardano-cli commands inside the container container_cli() { - docker exec -ti $container_name cardano-cli "$@" + docker exec -ti "$container_name" cardano-cli "$@" +} + +# Helper function to get UTXO with validation +get_utxo() { + local address=$1 + local utxo_output + utxo_output=$(container_cli conway query utxo --address "$address" --out-file /dev/stdout) + local utxo + utxo=$(echo "$utxo_output" | jq -r 'keys[0]') + if [ -z "$utxo" ] || [ "$utxo" = "null" ]; then + echo "Error: No UTXO found at address: $address" >&2 + exit 1 + fi + echo "$utxo" } # Send ada to the multisig payment script echo "Sending $LOVELACE_AMOUNT lovelace to $ADDRESS." +payment_addr=$(cat "$keys_dir/payment.addr") +utxo=$(get_utxo "$payment_addr") + echo "Building transaction" container_cli conway transaction build \ - --tx-in $(container_cli conway query utxo --address $(cat $keys_dir/payment.addr) --out-file /dev/stdout | jq -r 'keys[0]') \ - --tx-out "$ADDRESS"+$LOVELACE_AMOUNT \ - --change-address $(cat $keys_dir/payment.addr) \ + --tx-in "$utxo" \ + --tx-out "$ADDRESS+$LOVELACE_AMOUNT" \ + --change-address "$payment_addr" \ --out-file "$tx_unsigned_path" +# Check transaction file was created +if [ ! -f "$tx_unsigned_path" ]; then + echo "Error: Failed to create unsigned transaction file" + exit 1 +fi + container_cli conway transaction sign \ --tx-body-file "$tx_unsigned_path" \ - --signing-key-file $keys_dir/payment.skey \ + --signing-key-file "$keys_dir/payment.skey" \ --out-file "$tx_signed_path" +# Check signed transaction file was created +if [ ! -f "$tx_signed_path" ]; then + echo "Error: Failed to create signed transaction file" + exit 1 +fi + # Submit the transaction echo "Submitting transaction" -container_cli conway transaction submit --tx-file $tx_signed_path +container_cli conway transaction submit --tx-file "$tx_signed_path" diff --git a/scripts/simple/send-to-many.sh b/scripts/simple/send-to-many.sh index 981ae0c..ee8d7f9 100755 --- a/scripts/simple/send-to-many.sh +++ b/scripts/simple/send-to-many.sh @@ -1,20 +1,34 @@ #!/bin/bash +set -euo pipefail # ~~~~~~~~~~~~ CHANGE THIS ~~~~~~~~~~~~ LOVELACE_AMOUNT=1230000 -CSV_FILE="./keys/addresses-testnet.csv" -METADATA_FILE="./keys/metadata-testnet.json" # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Define directory paths -keys_dir="./keys" -txs_dir="./txs/simple/send-to-many" +# Get the script's directory and project root +script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" +txs_dir="$project_root/txs/simple" +CSV_FILE="$keys_dir/addresses-testnet.csv" +METADATA_FILE="$keys_dir/metadata-testnet.json" tx_path_stub="$txs_dir/send-to-many" tx_unsigned_path="$tx_path_stub.unsigned" tx_signed_path="$tx_path_stub.signed" -# Get the script's directory -script_dir=$(dirname "$0") +# Check required files exist +if [ ! -f "$keys_dir/payment.addr" ]; then + echo "Error: Payment address file not found: $keys_dir/payment.addr" + echo "Please run scripts/generate-keys.sh first" + exit 1 +fi + +if [ ! -f "$keys_dir/payment.skey" ]; then + echo "Error: Payment signing key not found: $keys_dir/payment.skey" + exit 1 +fi # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" @@ -28,7 +42,21 @@ echo "Using running container: $container_name" # Function to execute cardano-cli commands inside the container container_cli() { - docker exec -ti $container_name cardano-cli "$@" + docker exec -ti "$container_name" cardano-cli "$@" +} + +# Helper function to get UTXO with validation +get_utxo() { + local address=$1 + local utxo_output + utxo_output=$(container_cli conway query utxo --address "$address" --out-file /dev/stdout) + local utxo + utxo=$(echo "$utxo_output" | jq -r 'keys[0]') + if [ -z "$utxo" ] || [ "$utxo" = "null" ]; then + echo "Error: No UTXO found at address: $address" >&2 + exit 1 + fi + echo "$utxo" } # Check if CSV file exists @@ -69,14 +97,8 @@ echo "Found ${#addresses[@]} addresses in CSV file" echo "Sending $LOVELACE_AMOUNT lovelace to each address" # Get UTXO from payment address -payment_addr=$(cat $keys_dir/payment.addr) -utxo_output=$(container_cli conway query utxo --address "$payment_addr" --out-file /dev/stdout) -utxo=$(echo "$utxo_output" | jq -r 'keys[0]') - -if [ -z "$utxo" ] || [ "$utxo" = "null" ]; then - echo "Error: No UTXO found at payment address" - exit 1 -fi +payment_addr=$(cat "$keys_dir/payment.addr") +utxo=$(get_utxo "$payment_addr") echo "Using UTXO: $utxo" @@ -113,18 +135,30 @@ build_args+=("--out-file" "$tx_unsigned_path") container_cli "${build_args[@]}" +# Check transaction file was created +if [ ! -f "$tx_unsigned_path" ]; then + echo "Error: Failed to create unsigned transaction file" + exit 1 +fi + # Sign the transaction echo "Signing transaction" container_cli conway transaction sign \ --tx-body-file "$tx_unsigned_path" \ - --signing-key-file $keys_dir/payment.skey \ + --signing-key-file "$keys_dir/payment.skey" \ --out-file "$tx_signed_path" +# Check signed transaction file was created +if [ ! -f "$tx_signed_path" ]; then + echo "Error: Failed to create signed transaction file" + exit 1 +fi + # Submit the transaction echo "Submitting transaction" -container_cli conway transaction submit --tx-file $tx_signed_path +container_cli conway transaction submit --tx-file "$tx_signed_path" echo "Transaction submitted successfully!" echo "Sent $LOVELACE_AMOUNT lovelace to ${#addresses[@]} addresses" diff --git a/scripts/simple/treasury-donate.sh b/scripts/simple/treasury-donate.sh index 33e1522..db40c77 100755 --- a/scripts/simple/treasury-donate.sh +++ b/scripts/simple/treasury-donate.sh @@ -1,18 +1,32 @@ #!/bin/bash +set -euo pipefail # ~~~~~~~~~~~~ CHANGE THIS ~~~~~~~~~~~~ LOVELACE_AMOUNT=10000000 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Define directory paths -keys_dir="./keys" -txs_dir="./txs" +# Get the script's directory and project root +script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" +txs_dir="$project_root/txs/simple" tx_path_stub="$txs_dir/treasury-donate" tx_unsigned_path="$tx_path_stub.unsigned" tx_signed_path="$tx_path_stub.signed" -# Get the script's directory -script_dir=$(dirname "$0") +# Check required files exist +if [ ! -f "$keys_dir/payment.addr" ]; then + echo "Error: Payment address file not found: $keys_dir/payment.addr" + echo "Please run scripts/generate-keys.sh first" + exit 1 +fi + +if [ ! -f "$keys_dir/payment.skey" ]; then + echo "Error: Payment signing key not found: $keys_dir/payment.skey" + exit 1 +fi # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" @@ -26,7 +40,21 @@ echo "Using running container: $container_name" # Function to execute cardano-cli commands inside the container container_cli() { - docker exec -ti $container_name cardano-cli "$@" + docker exec -ti "$container_name" cardano-cli "$@" +} + +# Helper function to get UTXO with validation +get_utxo() { + local address=$1 + local utxo_output + utxo_output=$(container_cli conway query utxo --address "$address" --out-file /dev/stdout) + local utxo + utxo=$(echo "$utxo_output" | jq -r 'keys[0]') + if [ -z "$utxo" ] || [ "$utxo" = "null" ]; then + echo "Error: No UTXO found at address: $address" >&2 + exit 1 + fi + echo "$utxo" } # Send ada to the multisig payment script @@ -34,18 +62,33 @@ echo "Sending $LOVELACE_AMOUNT lovelace to the treasury." echo "Building transaction" +payment_addr=$(cat "$keys_dir/payment.addr") +utxo=$(get_utxo "$payment_addr") + container_cli conway transaction build \ - --tx-in $(container_cli conway query utxo --address $(cat $keys_dir/payment.addr) --out-file /dev/stdout | jq -r 'keys[0]') \ - --change-address $(cat $keys_dir/payment.addr) \ - --treasury-donation $LOVELACE_AMOUNT \ + --tx-in "$utxo" \ + --change-address "$payment_addr" \ + --treasury-donation "$LOVELACE_AMOUNT" \ --out-file "$tx_unsigned_path" +# Check transaction file was created +if [ ! -f "$tx_unsigned_path" ]; then + echo "Error: Failed to create unsigned transaction file" + exit 1 +fi + container_cli conway transaction sign \ --tx-body-file "$tx_unsigned_path" \ - --signing-key-file $keys_dir/payment.skey \ + --signing-key-file "$keys_dir/payment.skey" \ --out-file "$tx_signed_path" +# Check signed transaction file was created +if [ ! -f "$tx_signed_path" ]; then + echo "Error: Failed to create signed transaction file" + exit 1 +fi + # Submit the transaction echo "Submitting transaction" -container_cli conway transaction submit --tx-file $tx_signed_path +container_cli conway transaction submit --tx-file "$tx_signed_path" diff --git a/scripts/stake/delegate-to-drep.sh b/scripts/stake/delegate-to-drep.sh index 96dbca4..d507da2 100755 --- a/scripts/stake/delegate-to-drep.sh +++ b/scripts/stake/delegate-to-drep.sh @@ -1,19 +1,43 @@ #!/bin/bash +set -euo pipefail # ~~~~~~~~~~~~ CHANGE THIS ~~~~~~~~~~~~ drep_id="3f3d4a84b800b34eb84c6151a955cdd823a0b99e3b886c725b8769e5" # keyhash of the drep # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Define directory paths -keys_dir="./keys" -txs_dir="./txs/stake" +# Get the script's directory and project root +script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" +txs_dir="$project_root/txs/stake" tx_path_stub="$txs_dir/vote-deleg" tx_cert_path="$tx_path_stub.cert" tx_unsigned_path="$tx_path_stub.unsigned" tx_signed_path="$tx_path_stub.signed" -# Get the script's directory -script_dir=$(dirname "$0") +# Check required files exist +if [ ! -f "$keys_dir/payment.addr" ]; then + echo "Error: Payment address file not found: $keys_dir/payment.addr" + echo "Please run scripts/generate-keys.sh first" + exit 1 +fi + +if [ ! -f "$keys_dir/payment.skey" ]; then + echo "Error: Payment signing key not found: $keys_dir/payment.skey" + exit 1 +fi + +if [ ! -f "$keys_dir/stake.vkey" ]; then + echo "Error: Stake verification key not found: $keys_dir/stake.vkey" + exit 1 +fi + +if [ ! -f "$keys_dir/stake.skey" ]; then + echo "Error: Stake signing key not found: $keys_dir/stake.skey" + exit 1 +fi # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" @@ -27,35 +51,70 @@ echo "Using running container: $container_name" # Function to execute cardano-cli commands inside the container container_cli() { - docker exec -ti $container_name cardano-cli "$@" + docker exec -ti "$container_name" cardano-cli "$@" +} + +# Helper function to get UTXO with validation +get_utxo() { + local address=$1 + local utxo_output + utxo_output=$(container_cli conway query utxo --address "$address" --out-file /dev/stdout) + local utxo + utxo=$(echo "$utxo_output" | jq -r 'keys[0]') + if [ -z "$utxo" ] || [ "$utxo" = "null" ]; then + echo "Error: No UTXO found at address: $address" >&2 + exit 1 + fi + echo "$utxo" } # Delegating to an DRep echo "Delegating you to DRep: $drep_id." container_cli conway stake-address vote-delegation-certificate \ - --stake-verification-key-file $keys_dir/stake.vkey \ + --stake-verification-key-file "$keys_dir/stake.vkey" \ --drep-key-hash "$drep_id" \ --out-file "$tx_cert_path" +# Check certificate file was created +if [ ! -f "$tx_cert_path" ]; then + echo "Error: Failed to create certificate file" + exit 1 +fi + echo "Building transaction" +payment_addr=$(cat "$keys_dir/payment.addr") +utxo=$(get_utxo "$payment_addr") + container_cli conway transaction build \ --witness-override 2 \ - --tx-in $(container_cli conway query utxo --address $(cat $keys_dir/payment.addr) --out-file /dev/stdout | jq -r 'keys[0]') \ - --change-address $(cat $keys_dir/payment.addr) \ + --tx-in "$utxo" \ + --change-address "$payment_addr" \ --certificate-file "$tx_cert_path" \ --out-file "$tx_unsigned_path" +# Check transaction file was created +if [ ! -f "$tx_unsigned_path" ]; then + echo "Error: Failed to create unsigned transaction file" + exit 1 +fi + echo "Signing transaction" container_cli conway transaction sign \ --tx-body-file "$tx_unsigned_path" \ - --signing-key-file $keys_dir/payment.skey \ - --signing-key-file $keys_dir/stake.skey \ + --signing-key-file "$keys_dir/payment.skey" \ + --signing-key-file "$keys_dir/stake.skey" \ --out-file "$tx_signed_path" +# Check signed transaction file was created +if [ ! -f "$tx_signed_path" ]; then + echo "Error: Failed to create signed transaction file" + exit 1 +fi + # Submit the transaction echo "Submitting transaction" -container_cli conway transaction submit --tx-file $tx_signed_path +container_cli conway transaction submit --tx-file "$tx_signed_path" diff --git a/scripts/stake/delegate-to-spo.sh b/scripts/stake/delegate-to-spo.sh index b72cece..f0067ea 100755 --- a/scripts/stake/delegate-to-spo.sh +++ b/scripts/stake/delegate-to-spo.sh @@ -1,19 +1,43 @@ #!/bin/bash +set -euo pipefail # ~~~~~~~~~~~~ CHANGE THIS ~~~~~~~~~~~~ spo_id="pool104flte3y29dprxcntacsuyznhduvlaza38gvp8yyhy2vvmfenxa" # keyhash of the SPO # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Define directory paths -keys_dir="./keys" -txs_dir="./txs/stake" +# Get the script's directory and project root +script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" +txs_dir="$project_root/txs/stake" tx_path_stub="$txs_dir/stake-pool-deleg" tx_cert_path="$tx_path_stub.cert" tx_unsigned_path="$tx_path_stub.unsigned" tx_signed_path="$tx_path_stub.signed" -# Get the script's directory -script_dir=$(dirname "$0") +# Check required files exist +if [ ! -f "$keys_dir/payment.addr" ]; then + echo "Error: Payment address file not found: $keys_dir/payment.addr" + echo "Please run scripts/generate-keys.sh first" + exit 1 +fi + +if [ ! -f "$keys_dir/payment.skey" ]; then + echo "Error: Payment signing key not found: $keys_dir/payment.skey" + exit 1 +fi + +if [ ! -f "$keys_dir/stake.vkey" ]; then + echo "Error: Stake verification key not found: $keys_dir/stake.vkey" + exit 1 +fi + +if [ ! -f "$keys_dir/stake.skey" ]; then + echo "Error: Stake signing key not found: $keys_dir/stake.skey" + exit 1 +fi # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" @@ -27,31 +51,66 @@ echo "Using running container: $container_name" # Function to execute cardano-cli commands inside the container container_cli() { - docker exec -ti $container_name cardano-cli "$@" + docker exec -ti "$container_name" cardano-cli "$@" +} + +# Helper function to get UTXO with validation +get_utxo() { + local address=$1 + local utxo_output + utxo_output=$(container_cli conway query utxo --address "$address" --out-file /dev/stdout) + local utxo + utxo=$(echo "$utxo_output" | jq -r 'keys[0]') + if [ -z "$utxo" ] || [ "$utxo" = "null" ]; then + echo "Error: No UTXO found at address: $address" >&2 + exit 1 + fi + echo "$utxo" } # Delegating to an SPO echo "Delegating you to SPO: $spo_id." -container-cli conway stake-address stake-delegation-certificate \ - --stake-verification-key-file $keys_dir/stake.vkey \ +container_cli conway stake-address stake-delegation-certificate \ + --stake-verification-key-file "$keys_dir/stake.vkey" \ --stake-pool-id "$spo_id" \ --out-file "$tx_cert_path" -container-cli conway transaction build \ +# Check certificate file was created +if [ ! -f "$tx_cert_path" ]; then + echo "Error: Failed to create certificate file" + exit 1 +fi + +payment_addr=$(cat "$keys_dir/payment.addr") +utxo=$(get_utxo "$payment_addr") + +container_cli conway transaction build \ --witness-override 2 \ - --tx-in $(container-cli query utxo --address $(cat $keys_dir/payment.addr) --out-file /dev/stdout | jq -r 'keys[0]') \ - --change-address $(cat $keys_dir/payment.addr) \ + --tx-in "$utxo" \ + --change-address "$payment_addr" \ --certificate-file "$tx_cert_path" \ --out-file "$tx_unsigned_path" -container-cli conway transaction sign \ +# Check transaction file was created +if [ ! -f "$tx_unsigned_path" ]; then + echo "Error: Failed to create unsigned transaction file" + exit 1 +fi + +container_cli conway transaction sign \ --tx-body-file "$tx_unsigned_path" \ - --signing-key-file $keys_dir/payment.skey \ - --signing-key-file $keys_dir/stake.skey \ + --signing-key-file "$keys_dir/payment.skey" \ + --signing-key-file "$keys_dir/stake.skey" \ --out-file "$tx_signed_path" +# Check signed transaction file was created +if [ ! -f "$tx_signed_path" ]; then + echo "Error: Failed to create signed transaction file" + exit 1 +fi + # Submit the transaction echo "Submitting transaction" -container_cli conway transaction submit --tx-file $tx_signed_path +container_cli conway transaction submit --tx-file "$tx_signed_path" diff --git a/scripts/stake/key-deregister.sh b/scripts/stake/key-deregister.sh index 4609d34..d54ea15 100755 --- a/scripts/stake/key-deregister.sh +++ b/scripts/stake/key-deregister.sh @@ -1,15 +1,39 @@ #!/bin/bash +set -euo pipefail -# Define directory paths -keys_dir="./keys" -txs_dir="./txs/stake" +# Get the script's directory and project root +script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" +txs_dir="$project_root/txs/stake" tx_path_stub="$txs_dir/stake-deregistration" tx_cert_path="$tx_path_stub.cert" tx_unsigned_path="$tx_path_stub.unsigned" tx_signed_path="$tx_path_stub.signed" -# Get the script's directory -script_dir=$(dirname "$0") +# Check required files exist +if [ ! -f "$keys_dir/payment.addr" ]; then + echo "Error: Payment address file not found: $keys_dir/payment.addr" + echo "Please run scripts/generate-keys.sh first" + exit 1 +fi + +if [ ! -f "$keys_dir/payment.skey" ]; then + echo "Error: Payment signing key not found: $keys_dir/payment.skey" + exit 1 +fi + +if [ ! -f "$keys_dir/stake.vkey" ]; then + echo "Error: Stake verification key not found: $keys_dir/stake.vkey" + exit 1 +fi + +if [ ! -f "$keys_dir/stake.skey" ]; then + echo "Error: Stake signing key not found: $keys_dir/stake.skey" + exit 1 +fi # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" @@ -23,33 +47,68 @@ echo "Using running container: $container_name" # Function to execute cardano-cli commands inside the container container_cli() { - docker exec -ti $container_name cardano-cli "$@" + docker exec -ti "$container_name" cardano-cli "$@" +} + +# Helper function to get UTXO with validation +get_utxo() { + local address=$1 + local utxo_output + utxo_output=$(container_cli conway query utxo --address "$address" --out-file /dev/stdout) + local utxo + utxo=$(echo "$utxo_output" | jq -r 'keys[0]') + if [ -z "$utxo" ] || [ "$utxo" = "null" ]; then + echo "Error: No UTXO found at address: $address" >&2 + exit 1 + fi + echo "$utxo" } # Unregistering your stake key echo "Deregistering your stake key." container_cli conway stake-address deregistration-certificate \ - --stake-verification-key-file $keys_dir/stake.vkey \ - --key-reg-deposit-amt $(container_cli conway query gov-state | jq -r .currentPParams.stakeAddressDeposit) \ + --stake-verification-key-file "$keys_dir/stake.vkey" \ + --key-reg-deposit-amt "$(container_cli conway query gov-state | jq -r '.currentPParams.stakeAddressDeposit')" \ --out-file "$tx_cert_path" +# Check certificate file was created +if [ ! -f "$tx_cert_path" ]; then + echo "Error: Failed to create certificate file" + exit 1 +fi + echo "Building transaction" +payment_addr=$(cat "$keys_dir/payment.addr") +utxo=$(get_utxo "$payment_addr") + container_cli conway transaction build \ --witness-override 2 \ - --tx-in $(container_cli conway query utxo --address $(cat $keys_dir/payment.addr) --out-file /dev/stdout | jq -r 'keys[0]') \ - --change-address $(cat $keys_dir/payment.addr) \ + --tx-in "$utxo" \ + --change-address "$payment_addr" \ --certificate-file "$tx_cert_path" \ --out-file "$tx_unsigned_path" +# Check transaction file was created +if [ ! -f "$tx_unsigned_path" ]; then + echo "Error: Failed to create unsigned transaction file" + exit 1 +fi + container_cli conway transaction sign \ --tx-body-file "$tx_unsigned_path" \ - --signing-key-file $keys_dir/payment.skey \ - --signing-key-file $keys_dir/stake.skey \ + --signing-key-file "$keys_dir/payment.skey" \ + --signing-key-file "$keys_dir/stake.skey" \ --out-file "$tx_signed_path" +# Check signed transaction file was created +if [ ! -f "$tx_signed_path" ]; then + echo "Error: Failed to create signed transaction file" + exit 1 +fi + # Submit the transaction echo "Submitting transaction" -container_cli conway transaction submit --tx-file $tx_signed_path +container_cli conway transaction submit --tx-file "$tx_signed_path" diff --git a/scripts/stake/key-register.sh b/scripts/stake/key-register.sh index bc808bd..2972ba1 100755 --- a/scripts/stake/key-register.sh +++ b/scripts/stake/key-register.sh @@ -1,15 +1,39 @@ #!/bin/bash +set -euo pipefail -# Define directory paths -keys_dir="./keys" -txs_dir="./txs/stake" +# Get the script's directory and project root +script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" +txs_dir="$project_root/txs/stake" tx_path_stub="$txs_dir/stake-register" tx_cert_path="$tx_path_stub.cert" tx_unsigned_path="$tx_path_stub.unsigned" tx_signed_path="$tx_path_stub.signed" -# Get the script's directory -script_dir=$(dirname "$0") +# Check required files exist +if [ ! -f "$keys_dir/payment.addr" ]; then + echo "Error: Payment address file not found: $keys_dir/payment.addr" + echo "Please run scripts/generate-keys.sh first" + exit 1 +fi + +if [ ! -f "$keys_dir/payment.skey" ]; then + echo "Error: Payment signing key not found: $keys_dir/payment.skey" + exit 1 +fi + +if [ ! -f "$keys_dir/stake.vkey" ]; then + echo "Error: Stake verification key not found: $keys_dir/stake.vkey" + exit 1 +fi + +if [ ! -f "$keys_dir/stake.skey" ]; then + echo "Error: Stake signing key not found: $keys_dir/stake.skey" + exit 1 +fi # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" @@ -23,35 +47,71 @@ echo "Using running container: $container_name" # Function to execute cardano-cli commands inside the container container_cli() { - docker exec -ti $container_name cardano-cli "$@" + docker exec -ti "$container_name" cardano-cli "$@" +} + +# Helper function to get UTXO with validation (supports index selection) +get_utxo() { + local address=$1 + local index=${2:-0} + local utxo_output + utxo_output=$(container_cli conway query utxo --address "$address" --out-file /dev/stdout) + local utxo + utxo=$(echo "$utxo_output" | jq -r "keys[$index]") + if [ -z "$utxo" ] || [ "$utxo" = "null" ]; then + echo "Error: No UTXO found at address: $address (index $index)" >&2 + exit 1 + fi + echo "$utxo" } # Registering your stake key echo "Registering your stake key." container_cli conway stake-address registration-certificate \ - --stake-verification-key-file $keys_dir/stake.vkey \ - --key-reg-deposit-amt "$(container_cli conway query gov-state | jq -r .currentPParams.stakeAddressDeposit)" \ + --stake-verification-key-file "$keys_dir/stake.vkey" \ + --key-reg-deposit-amt "$(container_cli conway query gov-state | jq -r '.currentPParams.stakeAddressDeposit')" \ --out-file "$tx_cert_path" +# Check certificate file was created +if [ ! -f "$tx_cert_path" ]; then + echo "Error: Failed to create certificate file" + exit 1 +fi + echo "Building transaction" +payment_addr=$(cat "$keys_dir/payment.addr") +utxo=$(get_utxo "$payment_addr" 1) + container_cli conway transaction build \ --witness-override 2 \ - --tx-in $(container_cli conway query utxo --address $(cat $keys_dir/payment.addr) --out-file /dev/stdout | jq -r 'keys[1]') \ - --change-address $(cat $keys_dir/payment.addr) \ + --tx-in "$utxo" \ + --change-address "$payment_addr" \ --certificate-file "$tx_cert_path" \ --out-file "$tx_unsigned_path" +# Check transaction file was created +if [ ! -f "$tx_unsigned_path" ]; then + echo "Error: Failed to create unsigned transaction file" + exit 1 +fi + echo "Signing transaction" container_cli conway transaction sign \ --tx-body-file "$tx_unsigned_path" \ - --signing-key-file $keys_dir/payment.skey \ - --signing-key-file $keys_dir/stake.skey \ + --signing-key-file "$keys_dir/payment.skey" \ + --signing-key-file "$keys_dir/stake.skey" \ --out-file "$tx_signed_path" +# Check signed transaction file was created +if [ ! -f "$tx_signed_path" ]; then + echo "Error: Failed to create signed transaction file" + exit 1 +fi + # Submit the transaction echo "Submitting transaction" -container_cli conway transaction submit --tx-file $tx_signed_path +container_cli conway transaction submit --tx-file "$tx_signed_path" diff --git a/scripts/stake/withdraw-rewards.sh b/scripts/stake/withdraw-rewards.sh index adf9449..aafade0 100755 --- a/scripts/stake/withdraw-rewards.sh +++ b/scripts/stake/withdraw-rewards.sh @@ -1,15 +1,40 @@ #!/bin/bash +set -euo pipefail -# Define directory paths -keys_dir="./keys" -txs_dir="./txs/stake" +# Get the script's directory and project root +script_dir=$(dirname "$0") +project_root=$(cd "$script_dir/../.." && pwd) + +# Define directory paths relative to project root +keys_dir="$project_root/keys" +txs_dir="$project_root/txs/stake" tx_path_stub="$txs_dir/stake-withdraw" tx_cert_path="$tx_path_stub.cert" tx_unsigned_path="$tx_path_stub.unsigned" tx_signed_path="$tx_path_stub.signed" -# Get the script's directory -script_dir=$(dirname "$0") +# Check required files exist +if [ ! -f "$keys_dir/payment.addr" ]; then + echo "Error: Payment address file not found: $keys_dir/payment.addr" + echo "Please run scripts/generate-keys.sh first" + exit 1 +fi + +if [ ! -f "$keys_dir/payment.skey" ]; then + echo "Error: Payment signing key not found: $keys_dir/payment.skey" + exit 1 +fi + +if [ ! -f "$keys_dir/stake.addr" ]; then + echo "Error: Stake address file not found: $keys_dir/stake.addr" + echo "Please run scripts/generate-keys.sh first" + exit 1 +fi + +if [ ! -f "$keys_dir/stake.skey" ]; then + echo "Error: Stake signing key not found: $keys_dir/stake.skey" + exit 1 +fi # Get the container name from the get-container script container_name="$("$script_dir/../helper/get-container.sh")" @@ -23,31 +48,61 @@ echo "Using running container: $container_name" # Function to execute cardano-cli commands inside the container container_cli() { - docker exec -ti $container_name cardano-cli "$@" + docker exec -ti "$container_name" cardano-cli "$@" +} + +# Helper function to get UTXO with validation +get_utxo() { + local address=$1 + local utxo_output + utxo_output=$(container_cli conway query utxo --address "$address" --out-file /dev/stdout) + local utxo + utxo=$(echo "$utxo_output" | jq -r 'keys[0]') + if [ -z "$utxo" ] || [ "$utxo" = "null" ]; then + echo "Error: No UTXO found at address: $address" >&2 + exit 1 + fi + echo "$utxo" } -stake_account_balance=$(container_cli conway query stake-address-info --address $(cat $keys_dir/stake.addr) | jq -r '.[0].rewardAccountBalance') +stake_account_balance=$(container_cli conway query stake-address-info --address "$(cat "$keys_dir/stake.addr")" | jq -r '.[0].rewardAccountBalance') # Send ada to the multisig payment script echo "Withdrawing all balance of $stake_account_balance from stake account." echo "Building transaction" +payment_addr=$(cat "$keys_dir/payment.addr") +stake_addr=$(cat "$keys_dir/stake.addr") +utxo=$(get_utxo "$payment_addr") + container_cli conway transaction build \ - --tx-in $(container_cli conway query utxo --address $(cat $keys_dir/payment.addr) --out-file /dev/stdout | jq -r 'keys[0]') \ - --change-address $(cat $keys_dir/payment.addr) \ - --withdrawal $(cat $keys_dir/stake.addr)+$stake_account_balance \ + --tx-in "$utxo" \ + --change-address "$payment_addr" \ + --withdrawal "$stake_addr+$stake_account_balance" \ --out-file "$tx_unsigned_path" +# Check transaction file was created +if [ ! -f "$tx_unsigned_path" ]; then + echo "Error: Failed to create unsigned transaction file" + exit 1 +fi + echo "Signing transaction" container_cli conway transaction sign \ --tx-body-file "$tx_unsigned_path" \ - --signing-key-file $keys_dir/payment.skey \ - --signing-key-file $keys_dir/stake.skey \ + --signing-key-file "$keys_dir/payment.skey" \ + --signing-key-file "$keys_dir/stake.skey" \ --out-file "$tx_signed_path" +# Check signed transaction file was created +if [ ! -f "$tx_signed_path" ]; then + echo "Error: Failed to create signed transaction file" + exit 1 +fi + # Submit the transaction echo "Submitting transaction" -container_cli conway transaction submit --tx-file $tx_signed_path +container_cli conway transaction submit --tx-file "$tx_signed_path" diff --git a/start-node.sh b/start-node.sh index ea92270..373e94c 100755 --- a/start-node.sh +++ b/start-node.sh @@ -1,4 +1,5 @@ #!/bin/bash +set -euo pipefail # Define colors RED='\033[0;31m' @@ -17,28 +18,83 @@ echo " / / / _ \/ ___/ __/ __ \/ _ \/ ________/ / / / __ \/ ___/ //_/ _ \/ ___ echo " / / / __(__ / /_/ / / / __/ /_/_____/ /_/ / /_/ / /__/ ,< / __/ / /_____/ /| / /_/ / /_/ / __/ " echo " /_/ \___/____/\__/_/ /_/\___/\__/ /_____/\____/\___/_/|_|\___/_/ /_/ |_/\____/\__,_/\___/ " echo " " -echo -e "${NC}" -echo -e "${GREEN}Welcome to the Testnet Docker Node!${NC}" -echo -e "${YELLOW}This script will help you set up and manage your Cardano testnet node(s).${NC}" echo -# Define the list of available networks -available_networks=("mainnet" "preprod" "preview" "sanchonet") - -# Prompt the user to select a network -echo -e "${CYAN}Please select a network:${NC}" -select network in "${available_networks[@]}"; do - if [ -n "$network" ]; then - echo -e "${GREEN}You have selected: $network${NC}" - break +# Check and display running nodes +show_running_nodes() { + local running_nodes + running_nodes=$(docker ps --format "{{.Names}}" | grep -E "^node-[^-]+-[^-]+-container$" || true) + + if [ -n "$running_nodes" ]; then + echo -e "${CYAN}Currently running Cardano node(s):${NC}" + echo "$running_nodes" | while read -r container; do + # Extract network and version from container name (node-network-version-container) + local network_version=$(echo "$container" | sed 's/node-\(.*\)-container/\1/') + echo -e " ${GREEN}✓${NC} ${CYAN}$container${NC} (${YELLOW}$network_version${NC})" + done + echo "" else - echo -e "${RED}Invalid selection. Please try again.${NC}" + echo -e "${YELLOW}No Cardano nodes are currently running.${NC}" + echo "" fi -done +} + +# Display running nodes +show_running_nodes + +# Define the list of available networks +available_networks=("mainnet" "preprod" "preview" "sanchonet") # Define the list of available node versions available_versions=("10.5.1" "10.5.3" "10.6.1") +# Initialize variables to avoid unbound variable errors +network="" +node_version="" + +# Check if running in non-interactive mode (e.g., CI/CD) +if [ ! -t 0 ]; then + # Non-interactive mode: read from stdin + read -r network_choice || true + if [ -n "$network_choice" ] && [ "$network_choice" -ge 1 ] && [ "$network_choice" -le ${#available_networks[@]} ]; then + network="${available_networks[$((network_choice - 1))]}" + echo -e "${GREEN}Selected network: $network${NC}" + else + echo -e "${RED}Error: Invalid network selection: $network_choice${NC}" + exit 1 + fi + + read -r version_choice || true + if [ -n "$version_choice" ] && [ "$version_choice" -ge 1 ] && [ "$version_choice" -le ${#available_versions[@]} ]; then + node_version="${available_versions[$((version_choice - 1))]}" + echo -e "${GREEN}Selected node version: $node_version${NC}" + else + echo -e "${RED}Error: Invalid version selection: $version_choice${NC}" + exit 1 + fi +else + # Interactive mode: use select + echo -e "${CYAN}Please select a network:${NC}" + select network in "${available_networks[@]}"; do + if [ -n "$network" ]; then + echo -e "${GREEN}You have selected: $network${NC}" + break + else + echo -e "${RED}Invalid selection. Please try again.${NC}" + fi + done + + echo -e "${CYAN}Please select a node version:${NC}" + select node_version in "${available_versions[@]}"; do + if [ -n "$node_version" ]; then + echo -e "${GREEN}You have selected: $node_version${NC}" + break + else + echo -e "${RED}Invalid selection. Please try again.${NC}" + fi + done +fi + # Function to assign a unique port based on version # This ensures different versions on the same network use different ports assign_port_for_version() { @@ -56,23 +112,76 @@ assign_port_for_version() { echo $port } -# Prompt the user to select a node version -echo -e "${CYAN}Please select a node version:${NC}" -select node_version in "${available_versions[@]}"; do - if [ -n "$node_version" ]; then - echo -e "${GREEN}You have selected: $node_version${NC}" - break +# Validate that both network and node_version are set +if [ -z "$network" ]; then + echo -e "${RED}Error: Network not selected${NC}" + exit 1 +fi + +if [ -z "$node_version" ]; then + echo -e "${RED}Error: Node version not selected${NC}" + exit 1 +fi + +# Check for running Cardano node containers +check_running_nodes() { + local running_nodes + running_nodes=$(docker ps --format "{{.Names}}" | grep -E "^node-[^-]+-[^-]+-container$" || true) + + if [ -n "$running_nodes" ]; then + echo -e "${YELLOW}Warning: You have the following Cardano node(s) already running:${NC}" + echo "$running_nodes" | while read -r container; do + echo -e " ${CYAN}- $container${NC}" + done + echo "" else - echo -e "${RED}Invalid selection. Please try again.${NC}" + echo -e "${GREEN}No Cardano nodes are currently running.${NC}" + echo "" fi -done + + echo "$running_nodes" +} + +# Check if the specific node is already running or exists +check_duplicate_node() { + local target_container="node-$network-$node_version-container" + local is_running + local exists + + # Check if container is running + is_running=$(docker ps --format "{{.Names}}" | grep -E "^${target_container}$" || true) + + # Check if container exists (even if stopped) + exists=$(docker ps -a --format "{{.Names}}" | grep -E "^${target_container}$" || true) + + if [ -n "$is_running" ]; then + echo -e "${RED}Error: Node '$target_container' is already running!${NC}" + echo -e "${YELLOW}Please stop it first using: ./stop-nodes.sh${NC}" + echo -e "${YELLOW}Or use a different network/version combination.${NC}" + exit 1 + elif [ -n "$exists" ]; then + echo -e "${YELLOW}Warning: Container '$target_container' exists but is not running.${NC}" + echo -e "${YELLOW}Removing existing container...${NC}" + docker rm -f "$target_container" 2>/dev/null || true + fi +} + +# Check for running nodes and display them +running_nodes=$(check_running_nodes) + +# Check if the specific node is already running +check_duplicate_node # Assign a unique port for this version NODE_PORT=$(assign_port_for_version "$node_version") echo -e "${BLUE}Assigned port: $NODE_PORT${NC}" +# Get the project root directory (where this script is located) +script_dir=$(dirname "$0") +project_root=$(cd "$script_dir" && pwd) + # Set directory locations -base_dir="$(pwd)" +base_dir="$project_root" node_dir="$base_dir/node-$network-$node_version" config_dir="$node_dir/config" db_dir="$node_dir/db" @@ -85,9 +194,14 @@ cc_dir="$tx_dir/cc" drep_dir="$tx_dir/drep" ga_dir="$tx_dir/ga" multi_sig_dir="$tx_dir/multi-sig" +simple_dir="$tx_dir/simple" +helper_dir="$tx_dir/helper" # Dumps dir -dumps_dir="./dumps/$network" +dumps_dir="$base_dir/dumps/$network" + +# Utilities dir +utilities_dir="$base_dir/utilities" # Base URL for node config files if [ "$network" = "sanchonet" ]; then @@ -126,8 +240,12 @@ create_dir "$cc_dir" create_dir "$drep_dir" create_dir "$ga_dir" create_dir "$multi_sig_dir" +create_dir "$simple_dir" +create_dir "$helper_dir" # Dumps dir create_dir "$dumps_dir" +# Utilities dir +create_dir "$utilities_dir" # List of JSON files to download config_files=( @@ -162,7 +280,15 @@ export NETWORK_ID=$(jq -r '.networkMagic' "$config_dir/shelley-genesis.json") # Substitute the variables in the docker-compose.yml file and start the Docker container echo -e "${CYAN}Starting the Docker container...${NC}" -envsubst < docker-compose.yml | docker-compose -f - up -d --build +# Use docker compose (plugin) if available, fallback to docker-compose (standalone) +if command -v docker >/dev/null 2>&1 && docker compose version >/dev/null 2>&1; then + envsubst < docker-compose.yml | docker compose -f - up -d --build +elif command -v docker-compose >/dev/null 2>&1; then + envsubst < docker-compose.yml | docker-compose -f - up -d --build +else + echo -e "${RED}Error: Neither 'docker compose' nor 'docker-compose' is available${NC}" + exit 1 +fi # Forward the logs to the terminal echo -e "${GREEN}Docker container logs:${NC}" diff --git a/stop-nodes.sh b/stop-nodes.sh index e746181..2e19840 100755 --- a/stop-nodes.sh +++ b/stop-nodes.sh @@ -1,4 +1,5 @@ #!/bin/bash +set -euo pipefail # Stop all cardano node containers matching the pattern node-*-*-container # This handles versioned containers (e.g., node-preprod-10.5.3-container)