chore: sync docs, config schemas, scripts, and meta task alignment
- Institutional / JVMTM / reserve-provenance / GRU transport + standards JSON - Validation and verify scripts (Blockscout labels, x402, GRU preflight, P1 local path) - Wormhole wiring in AGENTS, MCP_SETUP, MASTER_INDEX, 04-configuration README - Meta docs, integration gaps, live verification log, architecture updates - CI validate-config workflow updates Operator/LAN items, submodule working trees, and public token-aggregation edge routes remain follow-up (see TODOS_CONSOLIDATED P1). Made-with: Cursor
This commit is contained in:
@@ -29,8 +29,15 @@ One-line install (Debian/Ubuntu): `sudo apt install -y sshpass rsync dnsutils ip
|
||||
|
||||
- `backup-npmplus.sh` - Full NPMplus backup (database, API exports, certificates)
|
||||
- `check-contracts-on-chain-138.sh` - Check that Chain 138 deployed contracts have bytecode on-chain (`cast code` for 31 addresses; requires `cast` and RPC access). Use `[RPC_URL]` or env `RPC_URL_138`; `--dry-run` lists addresses only (no RPC calls); `SKIP_EXIT=1` to exit 0 when RPC unreachable.
|
||||
- `check-public-report-api.sh` - Verify that `explorer.d-bis.org/api/v1/report/*` and `/api/v1/networks` return token-aggregation JSON rather than Blockscout-style `/api/v1` responses. Use `SKIP_EXIT=1` for diagnostic-only mode. Set `SKIP_BRIDGE_ROUTES=0` to assert `/api/v1/bridge/routes`, and `SKIP_BRIDGE_PREFLIGHT=0` to assert `/api/v1/bridge/preflight` payload shape.
|
||||
- `check-token-aggregation-chain138-api.sh` - Hits tokens, pools, quote, `bridge/routes`, `bridge/status`, `bridge/preflight`, and networks on both `/api/v1/*` and `/token-aggregation/api/v1/*`. `BASE_URL=https://explorer.d-bis.org` (default) or `http://192.168.11.140`.
|
||||
- `check-gru-transport-preflight.sh` - Operator-focused GRU runtime preflight. Calls `/api/v1/bridge/preflight`, prints blocked pairs with `eligibilityBlockers` / `runtimeMissingRequirements`, and fails unless all active pairs are runtime-ready or `ALLOW_BLOCKED=1` is set.
|
||||
- `check-cstar-v2-transport-stack.sh` - Predeploy Forge verifier for the `c* V2` bridge stack. Runs the base V2 token suite, legacy reserve-verifier compatibility suite, V2 reserve/verifier full L1/L2 round-trip suite, and the core `CWMultiTokenBridge` round-trip suite.
|
||||
- `run-repo-green-test-path.sh` - Local deterministic green-path aggregate behind root `pnpm test`. Runs config validation, then the focused `smom-dbis-138` contract and service CI targets.
|
||||
- `check-completion-status.sh` - One-command summary of repo-completable checks, public report API health, and pointers to operator/external remaining work.
|
||||
- `reconcile-env-canonical.sh` - Emit recommended .env lines for Chain 138 (canonical source of truth); use to reconcile `smom-dbis-138/.env` with [CONTRACT_ADDRESSES_REFERENCE](../../docs/11-references/CONTRACT_ADDRESSES_REFERENCE.md). Usage: `./scripts/verify/reconcile-env-canonical.sh [--print]`
|
||||
- `check-deployer-balance-blockscout-vs-rpc.sh` - Compare deployer native balance from Blockscout API vs RPC (to verify index matches current chain); see [EXPLORER_AND_BLOCKSCAN_REFERENCE](../../docs/11-references/EXPLORER_AND_BLOCKSCAN_REFERENCE.md)
|
||||
- `sync-blockscout-address-labels-from-registry.sh` - Plan or sync Blockscout address labels from `address-registry-entry` JSON (`config/dbis-institutional/schemas/address-registry-entry.schema.json`: `blockscout.label`, `status: active`). Supports `--mode=http`, `--mode=db`, and `--mode=auto`; on the self-hosted Chain 138 explorer, `db` is the right live mode because `/api/v1/*` is token-aggregation, not a native Blockscout label-write API. DB mode writes primary labels into Blockscout `public.address_names` through CT `5000`. See `config/dbis-institutional/README.md` and [OMNL_DBIS_CORE_CHAIN138_SMART_VAULT_RTGS_RUNBOOK.md](../../docs/03-deployment/OMNL_DBIS_CORE_CHAIN138_SMART_VAULT_RTGS_RUNBOOK.md).
|
||||
- `check-dependencies.sh` - Verify required tools (bash, curl, jq, openssl, ssh)
|
||||
- `export-cloudflare-dns-records.sh` - Export Cloudflare DNS records
|
||||
- `export-npmplus-config.sh` - Export NPMplus proxy hosts and certificates via API
|
||||
@@ -43,7 +50,9 @@ One-line install (Debian/Ubuntu): `sudo apt install -y sshpass rsync dnsutils ip
|
||||
|
||||
## Task runners (no LAN vs from LAN)
|
||||
|
||||
- **From anywhere (no LAN/creds):** `../run-completable-tasks-from-anywhere.sh` — runs config validation, on-chain contract check, run-all-validation --skip-genesis, and reconcile-env-canonical.
|
||||
- **From anywhere (no LAN/creds):** `../run-completable-tasks-from-anywhere.sh` — runs config validation, on-chain contract check, run-all-validation --skip-genesis, public report API diagnostics, and reconcile-env-canonical.
|
||||
- **Completion snapshot:** `check-completion-status.sh` — summarizes what is complete locally and what still depends on operator or external execution.
|
||||
- **Full LAN execution order:** `../run-full-operator-completion-from-lan.sh` — starts with the token-aggregation `/api/v1` repair, then Wave 0, verification, E2E, and optional operator-only deployment steps. Use `--dry-run` first.
|
||||
- **From LAN (NPM_PASSWORD, optional PRIVATE_KEY):** `../run-operator-tasks-from-lan.sh` — runs W0-1 (NPMplus RPC fix), W0-3 (NPMplus backup), O-1 (Blockscout verification); use `--dry-run` to print commands only. See [ALL_TASKS_DETAILED_STEPS](../../docs/00-meta/ALL_TASKS_DETAILED_STEPS.md).
|
||||
|
||||
## Environment
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
# Check whether Chain 138 deployed tokens (cUSDT, cUSDC) support ERC-2612 permit or ERC-3009.
|
||||
# Used to determine x402 compatibility: thirdweb x402 requires permit or ERC-3009.
|
||||
#
|
||||
# Usage: ./scripts/verify/check-chain138-token-permit-support.sh [RPC_URL]
|
||||
# Usage: ./scripts/verify/check-chain138-token-permit-support.sh [RPC_URL] [--token SYMBOL=ADDRESS]...
|
||||
# RPC_URL: optional; default from RPC_URL_138 or CHAIN_138_RPC_URL or https://rpc-core.d-bis.org
|
||||
# --token SYMBOL=ADDRESS: optional; inspect custom token inventory (repeatable)
|
||||
# --dry-run: print RPC and token addresses only (no RPC calls).
|
||||
#
|
||||
# Exit: 0 if script runs; output is human-readable. Use output to fill CHAIN138_X402_TOKEN_SUPPORT.md.
|
||||
@@ -14,19 +15,55 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
cd "$PROJECT_ROOT"
|
||||
|
||||
[[ -f "${SCRIPT_DIR}/../lib/load-project-env.sh" ]] && source "${SCRIPT_DIR}/../lib/load-project-env.sh" 2>/dev/null || true
|
||||
|
||||
DRY_RUN=""
|
||||
RPC_ARG=""
|
||||
for a in "$@"; do
|
||||
if [[ "$a" == "--dry-run" ]]; then DRY_RUN=1; else [[ -z "$RPC_ARG" ]] && RPC_ARG="$a"; fi
|
||||
declare -A TOKENS=()
|
||||
TOKEN_ORDER=()
|
||||
|
||||
add_token() {
|
||||
local spec="$1"
|
||||
local symbol="${spec%%=*}"
|
||||
local address="${spec#*=}"
|
||||
if [[ -z "$symbol" || -z "$address" || "$symbol" == "$address" ]]; then
|
||||
echo "ERROR: invalid token spec '$spec' (expected SYMBOL=ADDRESS)" >&2
|
||||
exit 1
|
||||
fi
|
||||
TOKENS["$symbol"]="$address"
|
||||
TOKEN_ORDER+=("$symbol")
|
||||
}
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--dry-run)
|
||||
DRY_RUN=1
|
||||
shift
|
||||
;;
|
||||
--token)
|
||||
[[ $# -ge 2 ]] || { echo "ERROR: --token requires SYMBOL=ADDRESS" >&2; exit 1; }
|
||||
add_token "$2"
|
||||
shift 2
|
||||
;;
|
||||
--token=*)
|
||||
add_token "${1#--token=}"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
if [[ -z "$RPC_ARG" ]]; then
|
||||
RPC_ARG="$1"
|
||||
else
|
||||
add_token "$1"
|
||||
fi
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
RPC="${RPC_ARG:-${RPC_URL_138:-${CHAIN_138_RPC_URL:-https://rpc-core.d-bis.org}}}"
|
||||
|
||||
# Token name, address (from CHAIN138_TOKEN_ADDRESSES.md)
|
||||
declare -A TOKENS
|
||||
TOKENS[cUSDT]="0x93E66202A11B1772E55407B32B44e5Cd8eda7f22"
|
||||
TOKENS[cUSDC]="0xf22258f57794CC8E06237084b353Ab30fFfa640b"
|
||||
if [[ ${#TOKEN_ORDER[@]} -eq 0 ]]; then
|
||||
add_token "cUSDT=0x93E66202A11B1772E55407B32B44e5Cd8eda7f22"
|
||||
add_token "cUSDC=0xf22258f57794CC8E06237084b353Ab30fFfa640b"
|
||||
fi
|
||||
|
||||
# Test holder for nonces(address) call (any address is fine)
|
||||
HOLDER="0x0000000000000000000000000000000000000001"
|
||||
@@ -34,7 +71,7 @@ HOLDER="0x0000000000000000000000000000000000000001"
|
||||
if [[ -n "$DRY_RUN" ]]; then
|
||||
echo "=== Chain 138 token permit support check (--dry-run) ==="
|
||||
echo "RPC: $RPC"
|
||||
for sym in cUSDT cUSDC; do echo " $sym: ${TOKENS[$sym]}"; done
|
||||
for sym in "${TOKEN_ORDER[@]}"; do echo " $sym: ${TOKENS[$sym]}"; done
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -48,7 +85,7 @@ if ! command -v cast &>/dev/null; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for sym in cUSDT cUSDC; do
|
||||
for sym in "${TOKEN_ORDER[@]}"; do
|
||||
addr="${TOKENS[$sym]}"
|
||||
echo "--- $sym ($addr) ---"
|
||||
|
||||
|
||||
203
scripts/verify/check-chain138-x402-readiness.sh
Executable file
203
scripts/verify/check-chain138-x402-readiness.sh
Executable file
@@ -0,0 +1,203 @@
|
||||
#!/usr/bin/env bash
|
||||
# Check whether Chain 138 is operationally ready for x402 and whether its payment tokens are x402-capable.
|
||||
#
|
||||
# Usage:
|
||||
# ./scripts/verify/check-chain138-x402-readiness.sh [CORE_RPC] [PUBLIC_RPC] [EXPLORER_STATS] [--token SYMBOL=ADDRESS]...
|
||||
# ./scripts/verify/check-chain138-x402-readiness.sh --strict
|
||||
#
|
||||
# Exit codes:
|
||||
# 0 when the script runs successfully
|
||||
# 1 when --strict is used and x402 is not fully ready
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
cd "$PROJECT_ROOT"
|
||||
|
||||
STRICT=0
|
||||
POSITIONAL=()
|
||||
declare -A TOKENS=()
|
||||
TOKEN_ORDER=()
|
||||
|
||||
add_token() {
|
||||
local spec="$1"
|
||||
local symbol="${spec%%=*}"
|
||||
local address="${spec#*=}"
|
||||
if [[ -z "$symbol" || -z "$address" || "$symbol" == "$address" ]]; then
|
||||
echo "ERROR: invalid token spec '$spec' (expected SYMBOL=ADDRESS)" >&2
|
||||
exit 1
|
||||
fi
|
||||
TOKENS["$symbol"]="$address"
|
||||
TOKEN_ORDER+=("$symbol")
|
||||
}
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--strict)
|
||||
STRICT=1
|
||||
shift
|
||||
;;
|
||||
--token)
|
||||
[[ $# -ge 2 ]] || { echo "ERROR: --token requires SYMBOL=ADDRESS" >&2; exit 1; }
|
||||
add_token "$2"
|
||||
shift 2
|
||||
;;
|
||||
--token=*)
|
||||
add_token "${1#--token=}"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
POSITIONAL+=("$1")
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
CORE_RPC="${POSITIONAL[0]:-${RPC_URL_138:-${CHAIN_138_RPC_URL:-http://192.168.11.211:8545}}}"
|
||||
PUBLIC_RPC="${POSITIONAL[1]:-${PUBLIC_RPC_URL_138:-https://rpc.public-0138.defi-oracle.io}}"
|
||||
EXPLORER_STATS="${POSITIONAL[2]:-${EXPLORER_STATS_URL_138:-https://explorer.d-bis.org/api/v2/stats}}"
|
||||
|
||||
if [[ ${#TOKEN_ORDER[@]} -eq 0 ]]; then
|
||||
add_token "cUSDT=0x93E66202A11B1772E55407B32B44e5Cd8eda7f22"
|
||||
add_token "cUSDC=0xf22258f57794CC8E06237084b353Ab30fFfa640b"
|
||||
fi
|
||||
|
||||
HOLDER="0x0000000000000000000000000000000000000001"
|
||||
ZERO_BYTES32="0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||
|
||||
rpc_call() {
|
||||
local url="$1"
|
||||
local method="$2"
|
||||
local params="${3:-[]}"
|
||||
curl -sS --max-time 15 \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data "{\"jsonrpc\":\"2.0\",\"method\":\"${method}\",\"params\":${params},\"id\":1}" \
|
||||
"$url"
|
||||
}
|
||||
|
||||
json_field() {
|
||||
local json="$1"
|
||||
local jq_expr="$2"
|
||||
jq -r "$jq_expr" <<<"$json" 2>/dev/null || true
|
||||
}
|
||||
|
||||
http_status() {
|
||||
local url="$1"
|
||||
local body_file="$2"
|
||||
curl -k -sS --max-time 15 -o "$body_file" -w "%{http_code}" "$url"
|
||||
}
|
||||
|
||||
echo "=== Chain 138 x402 readiness ==="
|
||||
echo "Core RPC: $CORE_RPC"
|
||||
echo "Public RPC: $PUBLIC_RPC"
|
||||
echo "Explorer: $EXPLORER_STATS"
|
||||
echo ""
|
||||
|
||||
core_ok=0
|
||||
public_ok=0
|
||||
explorer_ok=0
|
||||
token_ready=0
|
||||
|
||||
core_block="n/a"
|
||||
core_peers="n/a"
|
||||
core_syncing="n/a"
|
||||
public_client="n/a"
|
||||
explorer_blocks="n/a"
|
||||
|
||||
if core_block_json="$(rpc_call "$CORE_RPC" "eth_blockNumber")"; then
|
||||
core_block="$(json_field "$core_block_json" '.result // "n/a"')"
|
||||
if [[ "$core_block" != "n/a" && "$core_block" != "null" ]]; then
|
||||
core_ok=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "$core_ok" -eq 1 ]]; then
|
||||
core_peers="$(json_field "$(rpc_call "$CORE_RPC" "net_peerCount")" '.result // "n/a"')"
|
||||
core_syncing="$(json_field "$(rpc_call "$CORE_RPC" "eth_syncing")" '.result')"
|
||||
fi
|
||||
|
||||
public_body_file="$(mktemp)"
|
||||
explorer_body_file="$(mktemp)"
|
||||
trap 'rm -f "$public_body_file" "$explorer_body_file"' EXIT
|
||||
|
||||
public_status="$(curl -k -sS --max-time 15 -o "$public_body_file" -w "%{http_code}" \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data '{"jsonrpc":"2.0","method":"web3_clientVersion","params":[],"id":1}' \
|
||||
"$PUBLIC_RPC" || true)"
|
||||
public_result="$(cat "$public_body_file" 2>/dev/null || true)"
|
||||
public_client="$(json_field "$public_result" '.result // empty')"
|
||||
if [[ "$public_status" == "200" && -n "$public_client" ]]; then
|
||||
public_ok=1
|
||||
fi
|
||||
|
||||
explorer_status="$(http_status "$EXPLORER_STATS" "$explorer_body_file" || true)"
|
||||
explorer_result="$(cat "$explorer_body_file" 2>/dev/null || true)"
|
||||
explorer_blocks="$(json_field "$explorer_result" '.total_blocks // "n/a"')"
|
||||
if [[ "$explorer_status" == "200" && "$explorer_blocks" != "n/a" && "$explorer_blocks" != "null" ]]; then
|
||||
explorer_ok=1
|
||||
fi
|
||||
|
||||
echo "Operational readiness"
|
||||
echo " core_rpc_ok: $core_ok"
|
||||
echo " core_block: $core_block"
|
||||
echo " core_peer_count: $core_peers"
|
||||
echo " core_syncing: $core_syncing"
|
||||
echo " public_rpc_ok: $public_ok"
|
||||
echo " public_rpc_http: ${public_status:-n/a}"
|
||||
echo " public_client: ${public_client:-n/a}"
|
||||
echo " explorer_ok: $explorer_ok"
|
||||
echo " explorer_http: ${explorer_status:-n/a}"
|
||||
echo " explorer_blocks: $explorer_blocks"
|
||||
echo ""
|
||||
|
||||
echo "Token compatibility"
|
||||
if ! command -v cast >/dev/null 2>&1; then
|
||||
echo " cast_available: 0"
|
||||
echo " note: install foundry/cast to perform on-chain permit checks"
|
||||
else
|
||||
echo " cast_available: 1"
|
||||
for sym in "${TOKEN_ORDER[@]}"; do
|
||||
addr="${TOKENS[$sym]}"
|
||||
permit_supported=0
|
||||
auth_supported=0
|
||||
|
||||
if cast call "$addr" "nonces(address)(uint256)" "$HOLDER" --rpc-url "$CORE_RPC" >/dev/null 2>&1; then
|
||||
permit_supported=1
|
||||
fi
|
||||
if cast call "$addr" "authorizationState(address,bytes32)(bool)" "$HOLDER" "$ZERO_BYTES32" --rpc-url "$CORE_RPC" >/dev/null 2>&1; then
|
||||
auth_supported=1
|
||||
fi
|
||||
if [[ "$permit_supported" -eq 1 || "$auth_supported" -eq 1 ]]; then
|
||||
token_ready=1
|
||||
fi
|
||||
|
||||
echo " ${sym}_address: $addr"
|
||||
echo " ${sym}_erc2612: $permit_supported"
|
||||
echo " ${sym}_erc3009: $auth_supported"
|
||||
done
|
||||
fi
|
||||
|
||||
echo ""
|
||||
if [[ "$core_ok" -eq 1 && "$public_ok" -eq 1 && "$explorer_ok" -eq 1 ]]; then
|
||||
echo "Operational verdict: Chain 138 edge services are healthy."
|
||||
else
|
||||
echo "Operational verdict: Chain 138 edge services are not fully healthy."
|
||||
fi
|
||||
|
||||
if [[ "$token_ready" -eq 1 ]]; then
|
||||
echo "Token verdict: At least one canonical Chain 138 payment token is x402-capable."
|
||||
else
|
||||
echo "Token verdict: Canonical Chain 138 payment tokens are still not x402-capable."
|
||||
fi
|
||||
|
||||
if [[ "$core_ok" -eq 1 && "$public_ok" -eq 1 && "$explorer_ok" -eq 1 && "$token_ready" -eq 1 ]]; then
|
||||
echo "x402 verdict: READY"
|
||||
else
|
||||
echo "x402 verdict: BLOCKED"
|
||||
echo " note: thirdweb x402 still needs an ERC-2612 or ERC-3009 payment token on Chain 138."
|
||||
fi
|
||||
|
||||
if [[ "$STRICT" -eq 1 && ! ( "$core_ok" -eq 1 && "$public_ok" -eq 1 && "$explorer_ok" -eq 1 && "$token_ready" -eq 1 ) ]]; then
|
||||
exit 1
|
||||
fi
|
||||
62
scripts/verify/check-completion-status.sh
Executable file
62
scripts/verify/check-completion-status.sh
Executable file
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env bash
|
||||
# Summarize repo-completable vs operator/external completion state in one place.
|
||||
# Usage: bash scripts/verify/check-completion-status.sh
|
||||
# Exit codes:
|
||||
# 0 = all repo-completable checks passed and public API looks healthy
|
||||
# 1 = one or more checks reported issues
|
||||
# Set SKIP_EXIT=1 to always exit 0 after printing the summary.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
cd "$PROJECT_ROOT"
|
||||
SKIP_EXIT="${SKIP_EXIT:-0}"
|
||||
FAILURES=0
|
||||
|
||||
section() {
|
||||
printf '\n=== %s ===\n' "$1"
|
||||
}
|
||||
|
||||
run_check() {
|
||||
local label="$1"
|
||||
shift
|
||||
printf -- '- %s\n' "$label"
|
||||
if "$@"; then
|
||||
printf ' [OK] %s\n' "$label"
|
||||
else
|
||||
printf ' [WARN] %s\n' "$label"
|
||||
FAILURES=$((FAILURES + 1))
|
||||
fi
|
||||
}
|
||||
|
||||
section "Repo-Completable Checks"
|
||||
run_check "Config validation" bash scripts/validation/validate-config-files.sh
|
||||
run_check "All validation (--skip-genesis)" bash scripts/verify/run-all-validation.sh --skip-genesis
|
||||
run_check "Submodule working trees" env SKIP_EXIT=0 bash scripts/verify/submodules-clean.sh
|
||||
|
||||
section "Public API Health"
|
||||
run_check "Public report API" env SKIP_EXIT=0 KEEP_GOING=1 bash scripts/verify/check-public-report-api.sh
|
||||
|
||||
section "Status Interpretation"
|
||||
cat <<'EOF'
|
||||
- Repo-local validation is complete when the config, validation, and submodule checks pass.
|
||||
- Public report API problems are usually operator-side nginx/proxy deployment issues, not repo code issues.
|
||||
- Remaining non-local work is tracked in:
|
||||
- docs/00-meta/STILL_NOT_DONE_EXECUTION_CHECKLIST.md
|
||||
- docs/00-meta/OPERATOR_AND_EXTERNAL_COMPLETION_CHECKLIST.md
|
||||
- docs/00-meta/COMPLETE_REQUIRED_OPTIONAL_RECOMMENDED_INDEX.md
|
||||
EOF
|
||||
|
||||
section "Summary"
|
||||
if (( FAILURES == 0 )); then
|
||||
echo "- All repo-completable checks passed."
|
||||
echo "- Public report API looks healthy."
|
||||
else
|
||||
echo "- Checks with warnings: $FAILURES"
|
||||
echo "- Review the warnings above to distinguish repo-local cleanup from operator-side work."
|
||||
fi
|
||||
|
||||
if (( FAILURES > 0 )) && [[ "$SKIP_EXIT" != "1" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
# Check that Chain 138 deployed contracts have bytecode on-chain.
|
||||
# Address list: 61 (core, CCIP, PMM, vault/reserve, oracle keeper path, CompliantFiatTokens). Source: CONTRACT_ADDRESSES_REFERENCE, ADDRESS_MATRIX.
|
||||
# Address list: 64 (core, CCIP canonical+legacy routers, WETH9 canonical+legacy bridges, PMM, vault/reserve, oracle keeper path, CompliantFiatTokens, ISO20022Router). Aligns with smom-dbis-138/.env and ADDRESS_MATRIX.
|
||||
# Usage: ./scripts/verify/check-contracts-on-chain-138.sh [RPC_URL] [--dry-run]
|
||||
# Default RPC: from env RPC_URL_138 (Chain 138 Core standard) or config/ip-addresses.conf, else https://rpc-core.d-bis.org
|
||||
# Optional: SKIP_EXIT=1 to exit 0 even when some addresses MISS (e.g. when RPC unreachable from this host).
|
||||
@@ -14,9 +14,17 @@ set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
export PROJECT_ROOT
|
||||
|
||||
# Load project env so RPC_URL_138 (Chain 138 Core) from config/ip-addresses.conf or smom-dbis-138/.env is used
|
||||
[[ -f "${SCRIPT_DIR}/../lib/load-project-env.sh" ]] && source "${SCRIPT_DIR}/../lib/load-project-env.sh" 2>/dev/null || true
|
||||
# Load project env so RPC_URL_138 (Chain 138 Core) from config/ip-addresses.conf or smom-dbis-138/.env is used.
|
||||
# export PROJECT_ROOT so load-project-env does not re-derive a wrong path from BASH_SOURCE and hit err_exit.
|
||||
# Temporarily relax -e/-u: nested dotenv may invoke helpers not on PATH or reference unset vars (exit 127 / set -u).
|
||||
if [[ -f "${SCRIPT_DIR}/../lib/load-project-env.sh" ]]; then
|
||||
set +eu
|
||||
# shellcheck source=../lib/load-project-env.sh
|
||||
source "${SCRIPT_DIR}/../lib/load-project-env.sh" 2>/dev/null || true
|
||||
set -euo pipefail
|
||||
fi
|
||||
|
||||
# Parse args: first non-option is RPC_URL; --dry-run = print only, no cast calls
|
||||
DRY_RUN=""
|
||||
@@ -49,9 +57,11 @@ else
|
||||
"0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f" # WETH10
|
||||
"0x99b3511a2d315a497c8112c1fdd8d508d4b1e506" # Multicall / Oracle Aggregator
|
||||
"0x3304b747e565a97ec8ac220b0b6a1f6ffdb837e6" # Oracle Proxy
|
||||
"0x8078A09637e47Fa5Ed34F626046Ea2094a5CDE5e" # CCIP Router
|
||||
"0x42DAb7b888Dd382bD5Adcf9E038dBF1fD03b4817" # CCIP Router (canonical; CCIP_ROUTER / relay path)
|
||||
"0x8078A09637e47Fa5Ed34F626046Ea2094a5CDE5e" # CCIP Router direct legacy (CCIP_ROUTER_DIRECT_LEGACY)
|
||||
"0x105F8A15b819948a89153505762444Ee9f324684" # CCIP Sender
|
||||
"0x971cD9D156f193df8051E48043C476e53ECd4693" # CCIPWETH9Bridge
|
||||
"0xcacfd227A040002e49e2e01626363071324f820a" # CCIPWETH9Bridge (canonical sendCrossChain)
|
||||
"0x971cD9D156f193df8051E48043C476e53ECd4693" # CCIPWETH9Bridge direct legacy (CCIPWETH9_BRIDGE_DIRECT_LEGACY)
|
||||
"0xe0E93247376aa097dB308B92e6Ba36bA015535D0" # CCIPWETH10Bridge
|
||||
"0xb7721dD53A8c629d9f1Ba31a5819AFe250002b03" # LINK
|
||||
"0x93E66202A11B1772E55407B32B44e5Cd8eda7f22" # cUSDT
|
||||
@@ -106,6 +116,7 @@ else
|
||||
"0x54dBd40cF05e15906A2C21f600937e96787f5679" # cCADC
|
||||
"0x290E52a8819A4fbD0714E517225429aA2B70EC6b" # cXAUC
|
||||
"0x94e408E26c6FD8F4ee00b54dF19082FDA07dC96E" # cXAUT
|
||||
"0xBf1BB3E73C2DB7c4aebCd7bf757cdD1C12dE9074" # ISO20022Router (explorer address-inventory ISO20022_ROUTER)
|
||||
)
|
||||
fi
|
||||
|
||||
|
||||
55
scripts/verify/check-cstar-v2-transport-stack.sh
Normal file
55
scripts/verify/check-cstar-v2-transport-stack.sh
Normal file
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env bash
|
||||
# Verify that the c* V2 token, reserve, and c* <-> cW* transport stack are green before deploy.
|
||||
# Usage: bash scripts/verify/check-cstar-v2-transport-stack.sh
|
||||
#
|
||||
# Env:
|
||||
# DRY_RUN=1 Print the commands without executing them
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
SMOM_ROOT="${PROJECT_ROOT}/smom-dbis-138"
|
||||
DRY_RUN="${DRY_RUN:-0}"
|
||||
|
||||
log() { printf '%s\n' "$*"; }
|
||||
ok() { printf '[OK] %s\n' "$*"; }
|
||||
|
||||
run() {
|
||||
if [[ "$DRY_RUN" == "1" ]]; then
|
||||
printf '[DRY_RUN] %s\n' "$*"
|
||||
return 0
|
||||
fi
|
||||
"$@"
|
||||
}
|
||||
|
||||
if ! command -v forge >/dev/null 2>&1; then
|
||||
printf '[FAIL] forge is required but not installed or not on PATH.\n' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log "=== c* V2 transport stack verifier ==="
|
||||
log "Repo: ${SMOM_ROOT}"
|
||||
log ""
|
||||
|
||||
pushd "$SMOM_ROOT" >/dev/null
|
||||
|
||||
# Foundry's JSON cache occasionally drifts when toolchain output shapes change.
|
||||
# Removing the generated cache keeps these focused suites reliable in CI and local runs.
|
||||
rm -f cache/solidity-files-cache.json
|
||||
|
||||
run forge test --match-path "test/compliance/CompliantFiatTokenV2.t.sol"
|
||||
ok "CompliantFiatTokenV2 base token suite passed."
|
||||
|
||||
run forge test --match-path "test/bridge/CWReserveVerifierVaultIntegration.t.sol"
|
||||
ok "Legacy reserve-verifier bridge compatibility suite passed."
|
||||
|
||||
run forge test --match-path "test/bridge/CWReserveVerifierVaultV2Integration.t.sol"
|
||||
ok "V2 reserve-verifier + full L1/L2 transport suite passed."
|
||||
|
||||
run forge test --match-path "test/bridge/CWMultiTokenBridge.t.sol"
|
||||
ok "Core CWMultiTokenBridge round-trip suite passed."
|
||||
|
||||
popd >/dev/null
|
||||
|
||||
log ""
|
||||
ok "c* V2 bridge and transport stack is green."
|
||||
103
scripts/verify/check-gru-transport-preflight.sh
Executable file
103
scripts/verify/check-gru-transport-preflight.sh
Executable file
@@ -0,0 +1,103 @@
|
||||
#!/usr/bin/env bash
|
||||
# Verify GRU Monetary Transport Layer runtime readiness via /api/v1/bridge/preflight.
|
||||
# Usage: bash scripts/verify/check-gru-transport-preflight.sh [base_url]
|
||||
# base_url: Optional API base, defaults to https://explorer.d-bis.org
|
||||
#
|
||||
# Exit codes:
|
||||
# 0 = endpoint healthy and, unless ALLOW_BLOCKED=1, no blocked pairs remain
|
||||
# 1 = endpoint unreachable, wrong payload, or blocked pairs remain
|
||||
#
|
||||
# Env:
|
||||
# SKIP_EXIT=1 Print diagnostics but always exit 0
|
||||
# ALLOW_BLOCKED=1 Treat blocked pairs as warnings instead of failures
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
BASE_URL="${1:-${BASE_URL:-https://explorer.d-bis.org}}"
|
||||
BASE_URL="${BASE_URL%/}"
|
||||
SKIP_EXIT="${SKIP_EXIT:-0}"
|
||||
ALLOW_BLOCKED="${ALLOW_BLOCKED:-0}"
|
||||
HAD_FAILURE=0
|
||||
|
||||
log() { printf '%s\n' "$*"; }
|
||||
ok() { printf '[OK] %s\n' "$*"; }
|
||||
warn() { printf '[WARN] %s\n' "$*"; }
|
||||
fail() {
|
||||
printf '[FAIL] %s\n' "$*"
|
||||
HAD_FAILURE=1
|
||||
if [[ "$SKIP_EXIT" != "1" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
tmp_body="$(mktemp)"
|
||||
trap 'rm -f "$tmp_body"' EXIT
|
||||
|
||||
fetch_preflight() {
|
||||
local prefix
|
||||
for prefix in "" "/token-aggregation"; do
|
||||
local url="${BASE_URL}${prefix}/api/v1/bridge/preflight"
|
||||
local code
|
||||
code="$(curl -sS -o "$tmp_body" -w "%{http_code}" -m 25 "$url" 2>/dev/null || echo "000")"
|
||||
if [[ "$code" == "200" ]]; then
|
||||
printf '%s\n' "$prefix"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
log "=== GRU Transport preflight ==="
|
||||
log "Base URL: $BASE_URL"
|
||||
log ""
|
||||
|
||||
if ! prefix="$(fetch_preflight)"; then
|
||||
fail "Could not fetch /api/v1/bridge/preflight on either /api/v1 or /token-aggregation/api/v1."
|
||||
fi
|
||||
|
||||
if ! jq -e '
|
||||
type == "object" and
|
||||
(.gruTransport | type == "object") and
|
||||
(.gruTransport.summary.transportPairs | type == "number") and
|
||||
(.gruTransport.blockedPairs | type == "array") and
|
||||
(.gruTransport.readyPairs | type == "array")
|
||||
' "$tmp_body" >/dev/null 2>&1; then
|
||||
summary="$(head -c 300 "$tmp_body" | tr '\n' ' ')"
|
||||
fail "Unexpected /api/v1/bridge/preflight payload shape. Sample: $summary"
|
||||
fi
|
||||
|
||||
transport_pairs="$(jq -r '.gruTransport.summary.transportPairs // 0' "$tmp_body")"
|
||||
runtime_ready_pairs="$(jq -r '.gruTransport.summary.runtimeReadyTransportPairs // 0' "$tmp_body")"
|
||||
blocked_pairs="$(jq -r '.gruTransport.blockedPairs | length' "$tmp_body")"
|
||||
ready_pairs="$(jq -r '.gruTransport.readyPairs | length' "$tmp_body")"
|
||||
|
||||
display_path="${prefix}/api/v1/bridge/preflight"
|
||||
if [[ -z "$prefix" ]]; then
|
||||
display_path="/api/v1/bridge/preflight"
|
||||
fi
|
||||
ok "Preflight endpoint reachable at ${display_path}"
|
||||
log "Transport pairs: $transport_pairs"
|
||||
log "Runtime-ready pairs: $runtime_ready_pairs"
|
||||
log "Ready pairs returned: $ready_pairs"
|
||||
log "Blocked pairs returned: $blocked_pairs"
|
||||
|
||||
if (( blocked_pairs > 0 )); then
|
||||
log ""
|
||||
warn "Blocked GRU transport pairs:"
|
||||
jq -r '
|
||||
.gruTransport.blockedPairs[]
|
||||
| "- \(.key): eligibilityBlockers=\(((.eligibilityBlockers // []) | join(",")) // "") runtimeMissingRequirements=\(((.runtimeMissingRequirements // []) | join(",")) // "")"
|
||||
' "$tmp_body"
|
||||
|
||||
if [[ "$ALLOW_BLOCKED" != "1" ]]; then
|
||||
fail "GRU transport preflight has blocked pairs. Set ALLOW_BLOCKED=1 for diagnostic-only mode."
|
||||
else
|
||||
warn "ALLOW_BLOCKED=1 set: blocked pairs reported without failing."
|
||||
fi
|
||||
else
|
||||
ok "All active GRU transport pairs are runtime-ready."
|
||||
fi
|
||||
|
||||
if [[ "$SKIP_EXIT" == "1" ]]; then
|
||||
warn "SKIP_EXIT=1 set: diagnostic mode."
|
||||
fi
|
||||
128
scripts/verify/check-public-report-api.sh
Executable file
128
scripts/verify/check-public-report-api.sh
Executable file
@@ -0,0 +1,128 @@
|
||||
#!/usr/bin/env bash
|
||||
# Verify that the public token-aggregation/report API is reachable and not misrouted to Blockscout.
|
||||
# Usage: bash scripts/verify/check-public-report-api.sh [base_url]
|
||||
# base_url: Optional API base, defaults to https://explorer.d-bis.org
|
||||
#
|
||||
# Exit codes:
|
||||
# 0 = all expected endpoints returned token-aggregation-style JSON
|
||||
# 1 = one or more endpoints returned the wrong shape or were unreachable
|
||||
# Set SKIP_EXIT=1 to print diagnostics but exit 0.
|
||||
# Set KEEP_GOING=1 to keep checking every endpoint before exiting non-zero.
|
||||
# Set SKIP_BRIDGE_ROUTES=0 to assert /api/v1/bridge/routes payload shape.
|
||||
# Set SKIP_BRIDGE_PREFLIGHT=0 to assert /api/v1/bridge/preflight payload shape.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
BASE_URL="${1:-https://explorer.d-bis.org}"
|
||||
SKIP_EXIT="${SKIP_EXIT:-0}"
|
||||
KEEP_GOING="${KEEP_GOING:-0}"
|
||||
HAD_FAILURE=0
|
||||
|
||||
log() { printf '%s\n' "$*"; }
|
||||
ok() { printf '[OK] %s\n' "$*"; }
|
||||
warn() { printf '[WARN] %s\n' "$*"; }
|
||||
fail() {
|
||||
printf '[FAIL] %s\n' "$*"
|
||||
HAD_FAILURE=1
|
||||
if [[ "$SKIP_EXIT" != "1" && "$KEEP_GOING" != "1" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_json_shape() {
|
||||
local name="$1"
|
||||
local url="$2"
|
||||
local jq_expr="$3"
|
||||
local expected_desc="$4"
|
||||
local response
|
||||
local body
|
||||
local status
|
||||
|
||||
if ! response="$(curl -sSL --max-time 20 -w $'\n%{http_code}' "$url" 2>/dev/null)"; then
|
||||
fail "$name request failed: $url"
|
||||
return 0
|
||||
fi
|
||||
|
||||
status="$(printf '%s' "$response" | tail -n 1)"
|
||||
body="$(printf '%s' "$response" | sed '$d')"
|
||||
|
||||
if printf '%s' "$body" | jq -e 'type == "object" and has("message") and has("result") and has("status")' >/dev/null 2>&1; then
|
||||
fail "$name is returning Blockscout-style JSON (HTTP $status) instead of token-aggregation JSON. See docs/04-configuration/TOKEN_AGGREGATION_REPORT_API_RUNBOOK.md"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if printf '%s' "$body" | jq -e 'type == "object" and has("error")' >/dev/null 2>&1; then
|
||||
local api_error
|
||||
api_error="$(printf '%s' "$body" | jq -r '.error' 2>/dev/null || echo 'unknown error')"
|
||||
fail "$name returned token-aggregation error payload (HTTP $status): $api_error"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if printf '%s' "$body" | jq -e "$jq_expr" >/dev/null 2>&1; then
|
||||
ok "$name healthy ($expected_desc, HTTP $status)"
|
||||
return 0
|
||||
fi
|
||||
|
||||
local summary
|
||||
summary="$(printf '%s' "$body" | head -c 240 | tr '\n' ' ')"
|
||||
fail "$name returned unexpected payload (HTTP $status). Expected $expected_desc. Sample: $summary"
|
||||
}
|
||||
|
||||
log "=== Public report API check ==="
|
||||
log "Base URL: $BASE_URL"
|
||||
log ""
|
||||
|
||||
check_json_shape \
|
||||
"token-list" \
|
||||
"$BASE_URL/api/v1/report/token-list?chainId=138" \
|
||||
'type == "object" and (.tokens | type == "array")' \
|
||||
'object with .tokens[]'
|
||||
|
||||
check_json_shape \
|
||||
"coingecko report" \
|
||||
"$BASE_URL/api/v1/report/coingecko?chainId=138" \
|
||||
'type == "object"' \
|
||||
'token-aggregation report JSON object'
|
||||
|
||||
check_json_shape \
|
||||
"cmc report" \
|
||||
"$BASE_URL/api/v1/report/cmc?chainId=138" \
|
||||
'type == "object"' \
|
||||
'token-aggregation report JSON object'
|
||||
|
||||
check_json_shape \
|
||||
"networks" \
|
||||
"$BASE_URL/api/v1/networks" \
|
||||
'type == "object" and (.networks | type == "array")' \
|
||||
'object with .networks[]'
|
||||
|
||||
# Bridge routes (requires token-aggregation build with GET /api/v1/bridge/routes). Off by default until edge is deployed.
|
||||
if [[ "${SKIP_BRIDGE_ROUTES:-1}" != "1" ]]; then
|
||||
check_json_shape \
|
||||
"bridge-routes" \
|
||||
"$BASE_URL/api/v1/bridge/routes" \
|
||||
'type == "object" and (.chain138Bridges | type == "object") and (.routes | type == "object")' \
|
||||
'object with .chain138Bridges and .routes'
|
||||
fi
|
||||
|
||||
# GRU preflight (shape only; does not require all pairs to be runtime-ready). Off by default until edge is deployed.
|
||||
if [[ "${SKIP_BRIDGE_PREFLIGHT:-1}" != "1" ]]; then
|
||||
check_json_shape \
|
||||
"bridge-preflight" \
|
||||
"$BASE_URL/api/v1/bridge/preflight" \
|
||||
'type == "object" and (.gruTransport | type == "object") and (.gruTransport.summary.transportPairs | type == "number") and (.gruTransport.blockedPairs | type == "array")' \
|
||||
'object with .gruTransport.summary and .gruTransport.blockedPairs[]'
|
||||
fi
|
||||
|
||||
log ""
|
||||
if (( HAD_FAILURE > 0 )); then
|
||||
if [[ "$SKIP_EXIT" == "1" ]]; then
|
||||
warn "SKIP_EXIT=1 set: non-healthy endpoints were reported without failing."
|
||||
elif [[ "$KEEP_GOING" == "1" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
elif [[ "$SKIP_EXIT" == "1" ]]; then
|
||||
warn "SKIP_EXIT=1 set: non-healthy endpoints were reported without failing."
|
||||
else
|
||||
ok "Public report API endpoints look healthy."
|
||||
fi
|
||||
121
scripts/verify/check-rpc-fqdns-e2e.sh
Executable file
121
scripts/verify/check-rpc-fqdns-e2e.sh
Executable file
@@ -0,0 +1,121 @@
|
||||
#!/usr/bin/env bash
|
||||
# E2E: every public RPC FQDN — HTTP JSON-RPC eth_chainId (+ WSS where listed).
|
||||
# Exit 0 only if all HTTP checks pass; WSS failures warn unless STRICT_WSS=1 (then exit 1).
|
||||
#
|
||||
# Usage: bash scripts/verify/check-rpc-fqdns-e2e.sh
|
||||
# Env: RPC_TIMEOUT_SEC (default 25), STRICT_WSS=1 to fail on wscat errors
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
TO="${RPC_TIMEOUT_SEC:-25}"
|
||||
BODY='{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}'
|
||||
# Chain 138
|
||||
EXPECT='0x8a'
|
||||
|
||||
# HTTP JSON-RPC hostnames (inventory: verify-end-to-end-routing.sh + RPC_ENDPOINTS_MASTER + NPM tw-core / core-2)
|
||||
HTTP_FQDNS=(
|
||||
rpc-http-pub.d-bis.org
|
||||
rpc.d-bis.org
|
||||
rpc2.d-bis.org
|
||||
rpc-http-prv.d-bis.org
|
||||
rpc-fireblocks.d-bis.org
|
||||
rpc.public-0138.defi-oracle.io
|
||||
rpc.defi-oracle.io
|
||||
rpc-alltra.d-bis.org
|
||||
rpc-alltra-2.d-bis.org
|
||||
rpc-alltra-3.d-bis.org
|
||||
rpc-hybx.d-bis.org
|
||||
rpc-hybx-2.d-bis.org
|
||||
rpc-hybx-3.d-bis.org
|
||||
rpc.tw-core.d-bis.org
|
||||
rpc-core-2.d-bis.org
|
||||
rpc-core.d-bis.org
|
||||
)
|
||||
|
||||
# WebSocket RPC hostnames (wss://)
|
||||
WS_FQDNS=(
|
||||
rpc-ws-pub.d-bis.org
|
||||
ws.rpc.d-bis.org
|
||||
ws.rpc2.d-bis.org
|
||||
rpc-ws-prv.d-bis.org
|
||||
ws.rpc-fireblocks.d-bis.org
|
||||
wss.defi-oracle.io
|
||||
wss.tw-core.d-bis.org
|
||||
)
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "RPC FQDN E2E — eth_chainId (HTTP) + WSS smoke"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
|
||||
http_fail=0
|
||||
echo -e "${BLUE}--- HTTP (POST / JSON-RPC) ---${NC}"
|
||||
for host in "${HTTP_FQDNS[@]}"; do
|
||||
url="https://${host}"
|
||||
if ! getent ahosts "$host" >/dev/null 2>&1; then
|
||||
echo -e "${YELLOW}SKIP${NC} $url — hostname does not resolve (add DNS or use Core IP :8545)"
|
||||
continue
|
||||
fi
|
||||
resp=$(mktemp)
|
||||
code=$(curl -sS -m "$TO" -X POST "$url" \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d "$BODY" \
|
||||
-k -w '%{http_code}' -o "$resp" 2>/dev/null || echo "000")
|
||||
cid=$(jq -r '.result // empty' "$resp" 2>/dev/null || true)
|
||||
err=$(head -c 120 "$resp" 2>/dev/null | tr -d '\r\n')
|
||||
rm -f "$resp"
|
||||
if [[ "$code" == "200" && "$cid" == "$EXPECT" ]]; then
|
||||
echo -e "${GREEN}OK${NC} $url chainId=$cid"
|
||||
elif [[ "$code" == "200" && -n "$cid" ]]; then
|
||||
echo -e "${YELLOW}WARN${NC} $url HTTP $code chainId=$cid (expected $EXPECT)"
|
||||
((http_fail++)) || true
|
||||
else
|
||||
echo -e "${RED}FAIL${NC} $url HTTP $code ${err}"
|
||||
((http_fail++)) || true
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo -e "${BLUE}--- WebSocket (wscat eth_chainId) ---${NC}"
|
||||
ws_fail=0
|
||||
if ! command -v wscat >/dev/null 2>&1; then
|
||||
echo -e "${YELLOW}SKIP${NC} wscat not installed (npm i -g wscat)"
|
||||
ws_fail=0
|
||||
else
|
||||
for host in "${WS_FQDNS[@]}"; do
|
||||
if out=$(timeout "$((TO + 5))" wscat -n -c "wss://${host}" -x "$BODY" -w 8 2>&1); then
|
||||
if echo "$out" | grep -q '"result"'; then
|
||||
echo -e "${GREEN}OK${NC} wss://${host}"
|
||||
else
|
||||
echo -e "${YELLOW}OK*${NC} wss://${host} (connected, no JSON line)"
|
||||
fi
|
||||
else
|
||||
echo -e "${RED}FAIL${NC} wss://${host} $(echo "$out" | tail -1)"
|
||||
((ws_fail++)) || true
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
if [[ "$http_fail" -eq 0 ]]; then
|
||||
echo -e "${GREEN}HTTP: all passed ($EXPECT)${NC}"
|
||||
else
|
||||
echo -e "${RED}HTTP: $http_fail failure(s)${NC}"
|
||||
fi
|
||||
if [[ "${STRICT_WSS:-0}" == "1" ]] && [[ "$ws_fail" -gt 0 ]]; then
|
||||
echo -e "${RED}WSS: $ws_fail failure(s) (STRICT_WSS=1)${NC}"
|
||||
exit 1
|
||||
fi
|
||||
if [[ "$http_fail" -gt 0 ]]; then
|
||||
exit 1
|
||||
fi
|
||||
echo -e "${GREEN}Done.${NC}"
|
||||
exit 0
|
||||
68
scripts/verify/check-token-aggregation-chain138-api.sh
Executable file
68
scripts/verify/check-token-aggregation-chain138-api.sh
Executable file
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env bash
|
||||
# Verify token-aggregation HTTP surface for Chain 138 (pools, quotes, bridge routes, and GRU preflight).
|
||||
# Usage: BASE_URL=https://explorer.d-bis.org bash scripts/verify/check-token-aggregation-chain138-api.sh
|
||||
# Tries both /api/v1/* and /token-aggregation/api/v1/* (explorer nginx layouts differ).
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
BASE_URL="${BASE_URL:-https://explorer.d-bis.org}"
|
||||
BASE_URL="${BASE_URL%/}"
|
||||
|
||||
CUSDT="0x93E66202A11B1772E55407B32B44e5Cd8eda7f22"
|
||||
CUSDC="0xf22258f57794CC8E06237084b353Ab30fFfa640b"
|
||||
|
||||
try_path() {
|
||||
local prefix="$1"
|
||||
local path="$2"
|
||||
local url="${BASE_URL}${prefix}${path}"
|
||||
local code
|
||||
code=$(curl -sS -o /tmp/ta-check.json -w "%{http_code}" -m 25 "$url" || echo "000")
|
||||
echo " $code ${prefix}${path}"
|
||||
if [[ "$code" == 200 ]]; then
|
||||
head -c 220 /tmp/ta-check.json
|
||||
echo
|
||||
fi
|
||||
}
|
||||
|
||||
echo "== Token-aggregation checks against ${BASE_URL} =="
|
||||
for prefix in "" "/token-aggregation"; do
|
||||
echo ""
|
||||
echo "-- prefix: ${prefix:-/} (root /api/v1) --"
|
||||
try_path "${prefix}" "/api/v1/tokens?chainId=138&limit=3&includeDodoPool=true"
|
||||
try_path "${prefix}" "/api/v1/tokens/${CUSDT}/pools?chainId=138"
|
||||
try_path "${prefix}" "/api/v1/quote?chainId=138&tokenIn=${CUSDT}&tokenOut=${CUSDC}&amountIn=1000000"
|
||||
try_path "${prefix}" "/api/v1/bridge/routes"
|
||||
try_path "${prefix}" "/api/v1/bridge/status"
|
||||
try_path "${prefix}" "/api/v1/bridge/preflight"
|
||||
try_path "${prefix}" "/api/v1/networks"
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo ""
|
||||
echo "== bridge summary =="
|
||||
for prefix in "" "/token-aggregation"; do
|
||||
code=$(curl -sS -o /tmp/br.json -w "%{http_code}" -m 20 "${BASE_URL}${prefix}/api/v1/bridge/routes" 2>/dev/null || echo 000)
|
||||
echo "${prefix:-/} -> HTTP $code"
|
||||
if [[ "$code" == "200" ]] && command -v jq >/dev/null 2>&1; then
|
||||
jq '{weth9: .chain138Bridges.weth9, weth10: .chain138Bridges.weth10}' /tmp/br.json 2>/dev/null || head -c 200 /tmp/br.json
|
||||
echo
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "== bridge/preflight summary =="
|
||||
for prefix in "" "/token-aggregation"; do
|
||||
code=$(curl -sS -o /tmp/gru-preflight.json -w "%{http_code}" -m 20 "${BASE_URL}${prefix}/api/v1/bridge/preflight" 2>/dev/null || echo 000)
|
||||
echo "${prefix:-/} -> HTTP $code"
|
||||
if [[ "$code" == "200" ]] && command -v jq >/dev/null 2>&1; then
|
||||
jq '{transportPairs: .gruTransport.summary.transportPairs, runtimeReadyTransportPairs: .gruTransport.summary.runtimeReadyTransportPairs, blockedPairs: (.gruTransport.blockedPairs | length)}' /tmp/gru-preflight.json 2>/dev/null || head -c 200 /tmp/gru-preflight.json
|
||||
echo
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "Notes:"
|
||||
echo " - Empty tokens/pools: set DATABASE_URL + migrations; RPC to 138; PMM integration now defaults on-chain if env unset."
|
||||
echo " - bridge/routes 404: redeploy token-aggregation from repo (implements GET /api/v1/bridge/routes)."
|
||||
echo " - bridge/preflight blocked pairs: run bash scripts/verify/check-gru-transport-preflight.sh [BASE_URL] for exact missing refs."
|
||||
echo " - Health: curl -s http://127.0.0.1:3001/health on explorer VM (not always proxied as /health)."
|
||||
@@ -41,6 +41,7 @@ declare -A DOMAIN_ZONES=(
|
||||
["rpc-http-pub.d-bis.org"]="d-bis.org"
|
||||
["rpc-ws-pub.d-bis.org"]="d-bis.org"
|
||||
["rpc-http-prv.d-bis.org"]="d-bis.org"
|
||||
["rpc-core.d-bis.org"]="d-bis.org"
|
||||
["rpc-ws-prv.d-bis.org"]="d-bis.org"
|
||||
["dbis-admin.d-bis.org"]="d-bis.org"
|
||||
["dbis-api.d-bis.org"]="d-bis.org"
|
||||
|
||||
42
scripts/verify/run-p1-local-verification.sh
Executable file
42
scripts/verify/run-p1-local-verification.sh
Executable file
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env bash
|
||||
# P1 local verification — no LAN deploys, no Proxmox SSH, no on-chain txs.
|
||||
# Completes automatable slices documented in docs/00-meta/TODOS_CONSOLIDATED.md (P1-F*).
|
||||
#
|
||||
# Usage:
|
||||
# ./scripts/verify/run-p1-local-verification.sh # config + completable
|
||||
# ./scripts/verify/run-p1-local-verification.sh --with-iru-tests # + dbis_core pnpm test:iru-marketplace
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
WITH_IRU=0
|
||||
for a in "$@"; do
|
||||
[[ "$a" == "--with-iru-tests" ]] && WITH_IRU=1
|
||||
done
|
||||
|
||||
echo "== P1 local verification (repo root: $ROOT) =="
|
||||
echo ""
|
||||
|
||||
echo "[1/3] validate-config-files.sh"
|
||||
bash scripts/validation/validate-config-files.sh
|
||||
echo ""
|
||||
|
||||
echo "[2/3] run-completable-tasks-from-anywhere.sh"
|
||||
./scripts/run-completable-tasks-from-anywhere.sh
|
||||
echo ""
|
||||
|
||||
if [[ "$WITH_IRU" -eq 1 ]]; then
|
||||
echo "[3/3] dbis_core pnpm test:iru-marketplace"
|
||||
if command -v pnpm &>/dev/null; then
|
||||
(cd dbis_core && pnpm test:iru-marketplace)
|
||||
else
|
||||
echo "SKIP: pnpm not installed; run: cd dbis_core && pnpm test:iru-marketplace"
|
||||
fi
|
||||
else
|
||||
echo "[3/3] SKIP IRU tests (pass --with-iru-tests to run)"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "[OK] P1 local verification finished."
|
||||
27
scripts/verify/run-repo-green-test-path.sh
Executable file
27
scripts/verify/run-repo-green-test-path.sh
Executable file
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env bash
|
||||
# Run the repo's local deterministic green-path tests for Chain 138 / GRU transport.
|
||||
# Usage: bash scripts/verify/run-repo-green-test-path.sh
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
|
||||
log() { printf '%s\n' "$*"; }
|
||||
ok() { printf '[OK] %s\n' "$*"; }
|
||||
|
||||
run_step() {
|
||||
local label="$1"
|
||||
shift
|
||||
log ""
|
||||
log "=== ${label} ==="
|
||||
"$@"
|
||||
}
|
||||
|
||||
run_step "Config validation" \
|
||||
bash "$PROJECT_ROOT/scripts/validation/validate-config-files.sh"
|
||||
|
||||
run_step "Chain 138 package CI targets" \
|
||||
pnpm --dir "$PROJECT_ROOT/smom-dbis-138" run test:ci
|
||||
|
||||
log ""
|
||||
ok "Repo green-path tests passed."
|
||||
@@ -1,9 +1,11 @@
|
||||
#!/usr/bin/env bash
|
||||
# Exit 0 if every submodule has a clean working tree (no modified/untracked files).
|
||||
# Use in CI or after merges: bash scripts/verify/submodules-clean.sh
|
||||
# Set SKIP_EXIT=1 to report dirty submodules without failing.
|
||||
set -euo pipefail
|
||||
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
|
||||
cd "$ROOT"
|
||||
SKIP_EXIT="${SKIP_EXIT:-0}"
|
||||
|
||||
tmp="$(mktemp)"
|
||||
trap 'rm -f "$tmp"' EXIT
|
||||
@@ -25,7 +27,10 @@ done < <(git config --file .gitmodules --get-regexp '^submodule\..*\.path$' | aw
|
||||
if (( dirty )); then
|
||||
echo "submodules-clean: dirty submodule working trees:" >&2
|
||||
cat "$tmp" >&2
|
||||
exit 1
|
||||
if [[ "$SKIP_EXIT" != "1" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "submodules-clean: OK (all submodules clean)"
|
||||
|
||||
284
scripts/verify/sync-blockscout-address-labels-from-registry.sh
Executable file
284
scripts/verify/sync-blockscout-address-labels-from-registry.sh
Executable file
@@ -0,0 +1,284 @@
|
||||
#!/usr/bin/env bash
|
||||
# Sync address labels from DBIS institutional registry JSON into Blockscout.
|
||||
# Default: print the planned action only. Use --apply to write.
|
||||
#
|
||||
# Supported modes:
|
||||
# http - POST JSON to a Blockscout-compatible label endpoint
|
||||
# db - write primary labels directly into Blockscout Postgres address_names
|
||||
# auto - prefer HTTP if the route exists; otherwise fall back to DB sync
|
||||
#
|
||||
# Registry shape: config/dbis-institutional/schemas/address-registry-entry.schema.json
|
||||
#
|
||||
# Env (HTTP mode):
|
||||
# BLOCKSCOUT_BASE_URL default https://explorer.d-bis.org
|
||||
# BLOCKSCOUT_LABEL_PATH default /api/v1/labels
|
||||
# BLOCKSCOUT_API_KEY optional Bearer token if the endpoint requires it
|
||||
#
|
||||
# Env (DB mode):
|
||||
# BLOCKSCOUT_DB_SSH_HOST default root@192.168.11.12
|
||||
# BLOCKSCOUT_DB_CT_VMID default 5000
|
||||
# BLOCKSCOUT_DB_CONTAINER default blockscout-postgres
|
||||
# BLOCKSCOUT_DB_USER default blockscout
|
||||
# BLOCKSCOUT_DB_NAME default blockscout
|
||||
#
|
||||
# Usage:
|
||||
# bash scripts/verify/sync-blockscout-address-labels-from-registry.sh file1.json [file2.json ...]
|
||||
# bash scripts/verify/sync-blockscout-address-labels-from-registry.sh --from-dir config/dbis-institutional/registry
|
||||
# bash scripts/verify/sync-blockscout-address-labels-from-registry.sh --apply --mode=db --from-dir config/dbis-institutional/registry
|
||||
#
|
||||
set -euo pipefail
|
||||
|
||||
APPLY=0
|
||||
FROM_DIR=""
|
||||
SYNC_MODE="${BLOCKSCOUT_SYNC_MODE:-auto}"
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--apply) APPLY=1; shift ;;
|
||||
--from-dir=*)
|
||||
FROM_DIR="${1#*=}"
|
||||
shift
|
||||
;;
|
||||
--from-dir)
|
||||
FROM_DIR="${2:?}"
|
||||
shift 2
|
||||
;;
|
||||
--mode=*)
|
||||
SYNC_MODE="${1#*=}"
|
||||
shift
|
||||
;;
|
||||
--mode)
|
||||
SYNC_MODE="${2:?}"
|
||||
shift 2
|
||||
;;
|
||||
-h|--help)
|
||||
sed -n '2,42p' "$0" | sed 's/^# \{0,1\}//'
|
||||
exit 0
|
||||
;;
|
||||
*) break ;;
|
||||
esac
|
||||
done
|
||||
|
||||
case "$SYNC_MODE" in
|
||||
auto|http|db) ;;
|
||||
*)
|
||||
echo "error: --mode must be one of: auto, http, db" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
BASE_URL="${BLOCKSCOUT_BASE_URL:-https://explorer.d-bis.org}"
|
||||
LABEL_PATH="${BLOCKSCOUT_LABEL_PATH:-/api/v1/labels}"
|
||||
URL="${BASE_URL%/}${LABEL_PATH}"
|
||||
|
||||
BLOCKSCOUT_DB_SSH_HOST="${BLOCKSCOUT_DB_SSH_HOST:-root@192.168.11.12}"
|
||||
BLOCKSCOUT_DB_CT_VMID="${BLOCKSCOUT_DB_CT_VMID:-5000}"
|
||||
BLOCKSCOUT_DB_CONTAINER="${BLOCKSCOUT_DB_CONTAINER:-blockscout-postgres}"
|
||||
BLOCKSCOUT_DB_USER="${BLOCKSCOUT_DB_USER:-blockscout}"
|
||||
BLOCKSCOUT_DB_NAME="${BLOCKSCOUT_DB_NAME:-blockscout}"
|
||||
|
||||
files=()
|
||||
if [[ -n "$FROM_DIR" ]]; then
|
||||
if [[ ! -d "$FROM_DIR" ]]; then
|
||||
echo "error: --from-dir not a directory: $FROM_DIR" >&2
|
||||
exit 1
|
||||
fi
|
||||
while IFS= read -r -d '' f; do
|
||||
files+=("$f")
|
||||
done < <(find "$FROM_DIR" -maxdepth 1 -name '*.json' -print0 2>/dev/null || true)
|
||||
else
|
||||
files=("$@")
|
||||
fi
|
||||
|
||||
if [[ ${#files[@]} -eq 0 ]]; then
|
||||
echo "usage: $0 [--apply] [--mode auto|http|db] [--from-dir DIR] <registry.json> [...]" >&2
|
||||
echo " or: REGISTRY_DIR=... $0 --from-dir \"\$REGISTRY_DIR\"" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v jq &>/dev/null; then
|
||||
echo "error: jq is required" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sql_quote() {
|
||||
printf "%s" "$1" | sed "s/'/''/g"
|
||||
}
|
||||
|
||||
probe_http_sync() {
|
||||
local tmp status
|
||||
tmp=$(mktemp)
|
||||
status=$(curl -sS -o "$tmp" -w '%{http_code}' -X POST "$URL" -H 'Content-Type: application/json' --data '{}' || true)
|
||||
local body
|
||||
body=$(cat "$tmp")
|
||||
rm -f "$tmp"
|
||||
|
||||
# 2xx/4xx except 404 means the route exists and reached a handler.
|
||||
if [[ "$status" =~ ^(200|201|202|204|400|401|403|405|409|415|422)$ ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [[ "$status" == "404" && "$body" == *'"error":"Not found"'* ]]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
run_db_sql() {
|
||||
local sql="$1"
|
||||
ssh "$BLOCKSCOUT_DB_SSH_HOST" \
|
||||
"pct exec ${BLOCKSCOUT_DB_CT_VMID} -- docker exec -i ${BLOCKSCOUT_DB_CONTAINER} psql -U ${BLOCKSCOUT_DB_USER} -d ${BLOCKSCOUT_DB_NAME} -v ON_ERROR_STOP=1 -f -" \
|
||||
<<<"$sql"
|
||||
}
|
||||
|
||||
emit_http() {
|
||||
local display="$1"
|
||||
local address="$2"
|
||||
local label="$3"
|
||||
local ltype="$4"
|
||||
|
||||
local body
|
||||
body=$(jq -nc --arg a "$address" --arg l "$label" --arg t "$ltype" '{address:$a,label:$l,type:$t}')
|
||||
|
||||
if [[ "$APPLY" -ne 1 ]]; then
|
||||
echo "PLAN mode=http file=$display"
|
||||
echo " POST $URL"
|
||||
echo " $body"
|
||||
return 0
|
||||
fi
|
||||
|
||||
local hdr=()
|
||||
if [[ -n "${BLOCKSCOUT_API_KEY:-}" ]]; then
|
||||
hdr=(-H "Authorization: Bearer ${BLOCKSCOUT_API_KEY}" -H "Content-Type: application/json")
|
||||
else
|
||||
hdr=(-H "Content-Type: application/json")
|
||||
fi
|
||||
|
||||
echo "POST $display -> $URL"
|
||||
curl -fsS "${hdr[@]}" -X POST "$URL" -d "$body" >/dev/null
|
||||
echo "ok http $address"
|
||||
}
|
||||
|
||||
emit_db() {
|
||||
local display="$1"
|
||||
local address="$2"
|
||||
local label="$3"
|
||||
local ltype="$4"
|
||||
local normalized_address="${address#0x}"
|
||||
normalized_address="${normalized_address#0X}"
|
||||
normalized_address=$(printf '%s' "$normalized_address" | tr '[:upper:]' '[:lower:]')
|
||||
|
||||
if [[ ! "$normalized_address" =~ ^[0-9a-f]{40}$ ]]; then
|
||||
echo "skip (invalid address): $display" >&2
|
||||
return 0
|
||||
fi
|
||||
|
||||
local metadata
|
||||
metadata=$(jq -nc \
|
||||
--arg source "registry" \
|
||||
--arg registryFile "$display" \
|
||||
--arg labelType "$ltype" \
|
||||
'{source:$source,registryFile:$registryFile,labelType:$labelType}')
|
||||
|
||||
local sql
|
||||
sql=$(cat <<SQL
|
||||
INSERT INTO public.address_names (
|
||||
address_hash,
|
||||
name,
|
||||
"primary",
|
||||
inserted_at,
|
||||
updated_at,
|
||||
metadata
|
||||
)
|
||||
VALUES (
|
||||
decode('$(sql_quote "$normalized_address")', 'hex'),
|
||||
'$(sql_quote "$label")',
|
||||
true,
|
||||
NOW(),
|
||||
NOW(),
|
||||
'$(sql_quote "$metadata")'::jsonb
|
||||
)
|
||||
ON CONFLICT (address_hash) WHERE "primary" = true
|
||||
DO UPDATE SET
|
||||
name = EXCLUDED.name,
|
||||
updated_at = EXCLUDED.updated_at,
|
||||
metadata = COALESCE(public.address_names.metadata, '{}'::jsonb) || COALESCE(EXCLUDED.metadata, '{}'::jsonb);
|
||||
SQL
|
||||
)
|
||||
|
||||
if [[ "$APPLY" -ne 1 ]]; then
|
||||
echo "PLAN mode=db file=$display"
|
||||
echo " SSH $BLOCKSCOUT_DB_SSH_HOST -> CT $BLOCKSCOUT_DB_CT_VMID -> ${BLOCKSCOUT_DB_NAME}.public.address_names"
|
||||
echo " address=$address label=$label type=$ltype"
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "UPSERT $display -> ${BLOCKSCOUT_DB_NAME}.public.address_names"
|
||||
run_db_sql "$sql" >/dev/null
|
||||
echo "ok db $address"
|
||||
}
|
||||
|
||||
emit_one() {
|
||||
local file="$1"
|
||||
local display="${2:-$file}"
|
||||
local mode="$3"
|
||||
local blob
|
||||
blob=$(jq -e . "$file" 2>/dev/null) || { echo "skip (invalid JSON): $display" >&2; return 0; }
|
||||
|
||||
local status address label ltype
|
||||
status=$(echo "$blob" | jq -r '.status // "active"')
|
||||
[[ "$status" == "active" ]] || { echo "skip (status=$status): $display" >&2; return 0; }
|
||||
|
||||
address=$(echo "$blob" | jq -r '.address // empty')
|
||||
label=$(echo "$blob" | jq -r '.blockscout.label // empty')
|
||||
ltype=$(echo "$blob" | jq -r '.blockscout.labelType // "contract"')
|
||||
|
||||
if [[ -z "$address" || -z "$label" ]]; then
|
||||
echo "skip (missing address or blockscout.label): $display" >&2
|
||||
return 0
|
||||
fi
|
||||
|
||||
case "$mode" in
|
||||
http) emit_http "$display" "$address" "$label" "$ltype" ;;
|
||||
db) emit_db "$display" "$address" "$label" "$ltype" ;;
|
||||
*)
|
||||
echo "error: unsupported mode: $mode" >&2
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
SELECTED_MODE="$SYNC_MODE"
|
||||
if [[ "$SYNC_MODE" == "auto" && "$APPLY" -eq 1 ]]; then
|
||||
if probe_http_sync; then
|
||||
SELECTED_MODE="http"
|
||||
else
|
||||
SELECTED_MODE="db"
|
||||
fi
|
||||
fi
|
||||
|
||||
for f in "${files[@]}"; do
|
||||
[[ -f "$f" ]] || { echo "skip (not a file): $f" >&2; continue; }
|
||||
if jq -e 'type == "object" and (.address|type=="string")' "$f" &>/dev/null; then
|
||||
emit_one "$f" "$f" "$SELECTED_MODE" || exit 1
|
||||
elif jq -e 'type == "array"' "$f" &>/dev/null; then
|
||||
tmpdir=$(mktemp -d)
|
||||
len=$(jq 'length' "$f")
|
||||
for ((i = 0; i < len; i++)); do
|
||||
jq ".[$i]" "$f" >"$tmpdir/single.json"
|
||||
emit_one "$tmpdir/single.json" "$f (item $i)" "$SELECTED_MODE" || { rm -rf "$tmpdir"; exit 1; }
|
||||
done
|
||||
rm -rf "$tmpdir"
|
||||
else
|
||||
echo "skip (not object or array of objects): $f" >&2
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ "$APPLY" -ne 1 ]]; then
|
||||
echo ""
|
||||
echo "Dry run only. Re-run with --apply. Use --mode=db for this self-hosted Blockscout when /api/v1 labels is not available."
|
||||
else
|
||||
echo ""
|
||||
echo "Completed in mode=$SELECTED_MODE."
|
||||
fi
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
# Troubleshoot the 6 E2E RPC HTTP failures (405 at edge).
|
||||
# Troubleshoot E2E RPC HTTP failures (405 at edge); tests 7 primary FQDNs (+ optional --lan NPM Host checks).
|
||||
# Usage: bash scripts/verify/troubleshoot-rpc-failures.sh [--lan]
|
||||
# --lan Also test NPMplus direct (192.168.11.167) with Host header; requires LAN access.
|
||||
|
||||
@@ -17,6 +17,7 @@ RPC_DOMAINS=(
|
||||
"rpc.d-bis.org"
|
||||
"rpc2.d-bis.org"
|
||||
"rpc-http-prv.d-bis.org"
|
||||
"rpc-core.d-bis.org"
|
||||
"rpc.defi-oracle.io"
|
||||
)
|
||||
RPC_BODY='{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}'
|
||||
@@ -35,7 +36,7 @@ info() { echo -e "${BLUE}[INFO]${NC} $1"; }
|
||||
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "Troubleshoot 6 RPC E2E failures (POST → public IP)"
|
||||
echo "Troubleshoot RPC E2E failures (POST → public IP)"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
|
||||
|
||||
@@ -65,10 +65,13 @@ declare -A DOMAIN_TYPES_ALL=(
|
||||
["ws.rpc.d-bis.org"]="rpc-ws"
|
||||
["ws.rpc2.d-bis.org"]="rpc-ws"
|
||||
["rpc-http-prv.d-bis.org"]="rpc-http"
|
||||
["rpc-core.d-bis.org"]="rpc-http"
|
||||
["rpc-ws-prv.d-bis.org"]="rpc-ws"
|
||||
["rpc-fireblocks.d-bis.org"]="rpc-http"
|
||||
["ws.rpc-fireblocks.d-bis.org"]="rpc-ws"
|
||||
["admin.d-bis.org"]="web"
|
||||
["dbis-admin.d-bis.org"]="web"
|
||||
["core.d-bis.org"]="web"
|
||||
["dbis-api.d-bis.org"]="api"
|
||||
["dbis-api-2.d-bis.org"]="api"
|
||||
["secure.d-bis.org"]="web"
|
||||
@@ -111,6 +114,19 @@ declare -A DOMAIN_TYPES_ALL=(
|
||||
["gitea.d-bis.org"]="web"
|
||||
["dev.d-bis.org"]="web"
|
||||
["codespaces.d-bis.org"]="web"
|
||||
# DBIS institutional multi-portal program (optional-when-fail until provisioned)
|
||||
["d-bis.org"]="web"
|
||||
["www.d-bis.org"]="web"
|
||||
["members.d-bis.org"]="web"
|
||||
["developers.d-bis.org"]="web"
|
||||
["data.d-bis.org"]="api"
|
||||
["research.d-bis.org"]="web"
|
||||
["policy.d-bis.org"]="web"
|
||||
["ops.d-bis.org"]="web"
|
||||
["identity.d-bis.org"]="web"
|
||||
["status.d-bis.org"]="web"
|
||||
["sandbox.d-bis.org"]="web"
|
||||
["interop.d-bis.org"]="web"
|
||||
)
|
||||
# Private/admin profile domains (private RPC + Fireblocks RPC only).
|
||||
declare -a PRIVATE_PROFILE_DOMAINS=(
|
||||
@@ -174,7 +190,7 @@ else
|
||||
fi
|
||||
|
||||
# Domains that are optional when any test fails (off-LAN, 502, unreachable); fail → skip so run passes.
|
||||
_PUB_OPTIONAL_WHEN_FAIL="dapp.d-bis.org mifos.d-bis.org explorer.d-bis.org dbis-admin.d-bis.org dbis-api.d-bis.org dbis-api-2.d-bis.org secure.d-bis.org sankofa.nexus www.sankofa.nexus phoenix.sankofa.nexus www.phoenix.sankofa.nexus the-order.sankofa.nexus www.the-order.sankofa.nexus studio.sankofa.nexus keycloak.sankofa.nexus admin.sankofa.nexus portal.sankofa.nexus dash.sankofa.nexus docs.d-bis.org blockscout.defi-oracle.io mim4u.org www.mim4u.org secure.mim4u.org training.mim4u.org rpc-http-pub.d-bis.org rpc.d-bis.org rpc2.d-bis.org rpc.public-0138.defi-oracle.io rpc.defi-oracle.io ws.rpc.d-bis.org ws.rpc2.d-bis.org"
|
||||
_PUB_OPTIONAL_WHEN_FAIL="dapp.d-bis.org mifos.d-bis.org explorer.d-bis.org admin.d-bis.org dbis-admin.d-bis.org core.d-bis.org dbis-api.d-bis.org dbis-api-2.d-bis.org secure.d-bis.org d-bis.org www.d-bis.org members.d-bis.org developers.d-bis.org data.d-bis.org research.d-bis.org policy.d-bis.org ops.d-bis.org identity.d-bis.org status.d-bis.org sandbox.d-bis.org interop.d-bis.org sankofa.nexus www.sankofa.nexus phoenix.sankofa.nexus www.phoenix.sankofa.nexus the-order.sankofa.nexus www.the-order.sankofa.nexus studio.sankofa.nexus keycloak.sankofa.nexus admin.sankofa.nexus portal.sankofa.nexus dash.sankofa.nexus docs.d-bis.org blockscout.defi-oracle.io mim4u.org www.mim4u.org secure.mim4u.org training.mim4u.org rpc-http-pub.d-bis.org rpc.d-bis.org rpc2.d-bis.org rpc-core.d-bis.org rpc.public-0138.defi-oracle.io rpc.defi-oracle.io ws.rpc.d-bis.org ws.rpc2.d-bis.org"
|
||||
_PRIV_OPTIONAL_WHEN_FAIL="rpc-http-prv.d-bis.org rpc-ws-prv.d-bis.org rpc-fireblocks.d-bis.org ws.rpc-fireblocks.d-bis.org"
|
||||
if [[ -z "${E2E_OPTIONAL_WHEN_FAIL:-}" ]]; then
|
||||
if [[ "$PROFILE" == "private" ]]; then
|
||||
@@ -199,6 +215,7 @@ declare -A E2E_HTTPS_PATH=(
|
||||
["phoenix.sankofa.nexus"]="/health"
|
||||
["www.phoenix.sankofa.nexus"]="/health"
|
||||
["studio.sankofa.nexus"]="/studio/"
|
||||
["data.d-bis.org"]="/v1/health"
|
||||
)
|
||||
|
||||
# Expected apex URL for NPM www → canonical 301/308 (Location must use this host; path from E2E_HTTPS_PATH must appear when set)
|
||||
|
||||
Reference in New Issue
Block a user