- 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
204 lines
6.1 KiB
Bash
Executable File
204 lines
6.1 KiB
Bash
Executable File
#!/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
|