diff --git a/.gitea/workflows/check.yml b/.gitea/workflows/check.yml index d14b66e..7266ab7 100644 --- a/.gitea/workflows/check.yml +++ b/.gitea/workflows/check.yml @@ -17,3 +17,5 @@ jobs: run: | cd backend/secretapi go test ./... + - name: Validate deployment artifacts + run: ./scripts/check_deployment_artifacts.sh diff --git a/README.md b/README.md index 98c4813..1f52051 100644 --- a/README.md +++ b/README.md @@ -106,6 +106,7 @@ README.md ## Scripts 1. `scripts/publish_split_repos.sh` - creates/pushes `launcher`, `governance`, `contracts` repos using either a provided Gitea PAT or git credential-helper auth for `git.edut.dev`. +2. `scripts/check_deployment_artifacts.sh` - validates `docs/deployment/contract-addresses.base-sepolia.json` format and fail-closed parity assumptions. ## Internationalization diff --git a/scripts/check_deployment_artifacts.sh b/scripts/check_deployment_artifacts.sh new file mode 100755 index 0000000..7a2f072 --- /dev/null +++ b/scripts/check_deployment_artifacts.sh @@ -0,0 +1,81 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +FILE="$ROOT_DIR/docs/deployment/contract-addresses.base-sepolia.json" + +if ! command -v jq >/dev/null 2>&1; then + echo "FAIL: jq is required" + exit 1 +fi + +if [[ ! -f "$FILE" ]]; then + echo "FAIL: missing deployment artifact: $FILE" + exit 1 +fi + +check_eth_address() { + local value="$1" + if [[ ! "$value" =~ ^0x[0-9a-fA-F]{40}$ ]]; then + return 1 + fi + return 0 +} + +to_lower() { + printf "%s" "$1" | tr '[:upper:]' '[:lower:]' +} + +network="$(jq -r '.network // ""' "$FILE")" +chain_id="$(jq -r '.chain_id // 0' "$FILE")" +membership_contract="$(jq -r '.membership_contract // ""' "$FILE")" +entitlement_contract="$(jq -r '.entitlement_contract // ""' "$FILE")" +offer_registry_contract="$(jq -r '.offer_registry_contract // ""' "$FILE")" +treasury_wallet="$(jq -r '.treasury_wallet // ""' "$FILE")" +mint_currency_mode="$(jq -r '.mint_currency_mode // ""' "$FILE")" +mint_amount_atomic="$(jq -r '.mint_amount_atomic // ""' "$FILE")" +version="$(jq -r '.version // ""' "$FILE")" + +if [[ "$network" != "base-sepolia" ]]; then + echo "FAIL: unexpected network: $network" + exit 1 +fi +if [[ "$chain_id" != "84532" ]]; then + echo "FAIL: unexpected chain_id: $chain_id" + exit 1 +fi + +for addr_name in membership_contract entitlement_contract offer_registry_contract treasury_wallet; do + value="$(jq -r ".${addr_name} // \"\"" "$FILE")" + if ! check_eth_address "$value"; then + echo "FAIL: invalid address for ${addr_name}: ${value}" + exit 1 + fi +done + +if [[ "$(to_lower "$entitlement_contract")" != "$(to_lower "$offer_registry_contract")" ]]; then + echo "FAIL: entitlement_contract and offer_registry_contract diverged" + exit 1 +fi + +if [[ "$mint_currency_mode" != "ETH_TEST" && "$mint_currency_mode" != "USDC" ]]; then + echo "FAIL: invalid mint_currency_mode: $mint_currency_mode" + exit 1 +fi + +if [[ ! "$mint_amount_atomic" =~ ^[0-9]+$ ]]; then + echo "FAIL: invalid mint_amount_atomic: $mint_amount_atomic" + exit 1 +fi + +if [[ "$version" != "v1" ]]; then + echo "FAIL: unexpected deployment artifact version: $version" + exit 1 +fi + +echo "PASS: deployment artifact checks" +echo " network=$network chain_id=$chain_id" +echo " membership_contract=$membership_contract" +echo " entitlement_contract=$entitlement_contract" +echo " treasury_wallet=$treasury_wallet" +echo " mint_currency_mode=$mint_currency_mode mint_amount_atomic=$mint_amount_atomic"