126 lines
4.7 KiB
Bash
126 lines
4.7 KiB
Bash
|
|
#!/usr/bin/env bash
|
||
|
|
# Validate the repo's machine-readable Thirdweb account abstraction / x402 support matrix.
|
||
|
|
#
|
||
|
|
# Usage:
|
||
|
|
# bash scripts/verify/check-thirdweb-account-abstraction-support.sh
|
||
|
|
# bash scripts/verify/check-thirdweb-account-abstraction-support.sh --json
|
||
|
|
|
||
|
|
set -euo pipefail
|
||
|
|
|
||
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
|
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||
|
|
MATRIX_PATH="${PROJECT_ROOT}/config/thirdweb-account-abstraction-support.json"
|
||
|
|
OUTPUT_JSON=0
|
||
|
|
|
||
|
|
for arg in "$@"; do
|
||
|
|
case "$arg" in
|
||
|
|
--json) OUTPUT_JSON=1 ;;
|
||
|
|
*)
|
||
|
|
echo "Unknown argument: $arg" >&2
|
||
|
|
exit 2
|
||
|
|
;;
|
||
|
|
esac
|
||
|
|
done
|
||
|
|
|
||
|
|
if ! command -v jq >/dev/null 2>&1; then
|
||
|
|
echo "[FAIL] Missing required command: jq" >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
if [[ ! -f "$MATRIX_PATH" ]]; then
|
||
|
|
echo "[FAIL] Missing matrix file: $MATRIX_PATH" >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
summary_json="$(jq -c '
|
||
|
|
def chain($id): (.chains[] | select(.chainId == $id));
|
||
|
|
{
|
||
|
|
version,
|
||
|
|
updated,
|
||
|
|
dualModeAccountAbstraction: (.globalRequirements.dualModeAccountAbstraction == true),
|
||
|
|
chain138: {
|
||
|
|
currentDefault: (chain(138).accountAbstraction.currentDefault // null),
|
||
|
|
erc4337Supported: (chain(138).accountAbstraction.erc4337.supported == true),
|
||
|
|
eip7702Supported: (chain(138).accountAbstraction.eip7702.supported == true),
|
||
|
|
x402Enabled: (chain(138).x402.enabled == true),
|
||
|
|
x402SettlementMode: (chain(138).x402.settlementMode // null),
|
||
|
|
compatibleTokenCount: ((chain(138).x402.compatibleTokens // []) | length)
|
||
|
|
},
|
||
|
|
mainnet: {
|
||
|
|
currentDefault: (chain(1).accountAbstraction.currentDefault // null),
|
||
|
|
erc4337Supported: (chain(1).accountAbstraction.erc4337.supported == true),
|
||
|
|
eip7702Supported: (chain(1).accountAbstraction.eip7702.supported == true)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
' "$MATRIX_PATH")"
|
||
|
|
|
||
|
|
failures=()
|
||
|
|
|
||
|
|
assert_true() {
|
||
|
|
local jq_expr="$1"
|
||
|
|
local message="$2"
|
||
|
|
if [[ "$(jq -r "$jq_expr" "$MATRIX_PATH")" != "true" ]]; then
|
||
|
|
failures+=("$message")
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
|
||
|
|
assert_equals() {
|
||
|
|
local jq_expr="$1"
|
||
|
|
local expected="$2"
|
||
|
|
local message="$3"
|
||
|
|
if [[ "$(jq -r "$jq_expr" "$MATRIX_PATH")" != "$expected" ]]; then
|
||
|
|
failures+=("$message")
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
|
||
|
|
assert_true '.globalRequirements.dualModeAccountAbstraction == true' "dualModeAccountAbstraction must be true"
|
||
|
|
assert_true 'any(.chains[]; .chainId == 138)' "chainId 138 must be present"
|
||
|
|
assert_true 'any(.chains[]; .chainId == 1)' "chainId 1 must be present"
|
||
|
|
assert_true '(.chains[] | select(.chainId == 138) | .accountAbstraction.erc4337.supported) == true' "Chain 138 must support ERC-4337"
|
||
|
|
assert_true '(.chains[] | select(.chainId == 138) | .accountAbstraction.eip7702.supported) == true' "Chain 138 must record EIP-7702 support intent"
|
||
|
|
assert_equals '(.chains[] | select(.chainId == 138) | .accountAbstraction.currentDefault)' "erc4337" "Chain 138 currentDefault must remain erc4337 until 7702 is fully confirmed"
|
||
|
|
assert_equals '(.chains[] | select(.chainId == 138) | .x402.settlementMode)' "eip7702" "Chain 138 x402 settlement mode must be eip7702"
|
||
|
|
assert_true '((.chains[] | select(.chainId == 138) | .x402.compatibleTokens // []) | length) >= 1' "Chain 138 must list at least one x402-compatible token"
|
||
|
|
assert_true 'all((.chains[] | select(.chainId == 138) | .x402.compatibleTokens // [])[]; (.erc2612 == true) or (.erc3009 == true))' "Every Chain 138 x402 token must support ERC-2612 or ERC-3009"
|
||
|
|
assert_true '(.chains[] | select(.chainId == 1) | .accountAbstraction.erc4337.supported) == true' "Ethereum Mainnet must support ERC-4337"
|
||
|
|
assert_true '(.chains[] | select(.chainId == 1) | .accountAbstraction.eip7702.supported) == true' "Ethereum Mainnet must support EIP-7702"
|
||
|
|
|
||
|
|
if [[ "$OUTPUT_JSON" == "1" ]]; then
|
||
|
|
jq -n \
|
||
|
|
--argjson summary "$summary_json" \
|
||
|
|
--argjson failures "$(printf '%s\n' "${failures[@]:-}" | jq -R . | jq -s 'map(select(length > 0))')" \
|
||
|
|
'{
|
||
|
|
summary: $summary,
|
||
|
|
failures: $failures,
|
||
|
|
ok: (($failures | length) == 0)
|
||
|
|
}'
|
||
|
|
exit 0
|
||
|
|
fi
|
||
|
|
|
||
|
|
echo "=== Thirdweb Account Abstraction Support ==="
|
||
|
|
jq -r '
|
||
|
|
. as $root |
|
||
|
|
"Matrix version: \(.version)",
|
||
|
|
"Updated: \(.updated)",
|
||
|
|
"Dual-mode AA: \(.globalRequirements.dualModeAccountAbstraction)",
|
||
|
|
"",
|
||
|
|
(.chains[] | "Chain \(.chainId) (\(.name))",
|
||
|
|
" currentDefault: \(.accountAbstraction.currentDefault)",
|
||
|
|
" erc4337.supported: \(.accountAbstraction.erc4337.supported)",
|
||
|
|
" eip7702.supported: \(.accountAbstraction.eip7702.supported)",
|
||
|
|
" x402.enabled: \(.x402.enabled // false)",
|
||
|
|
" x402.settlementMode: \(.x402.settlementMode // "n/a")")
|
||
|
|
' "$MATRIX_PATH"
|
||
|
|
|
||
|
|
if [[ "${#failures[@]}" -gt 0 ]]; then
|
||
|
|
echo ""
|
||
|
|
echo "Failures:"
|
||
|
|
for failure in "${failures[@]}"; do
|
||
|
|
echo "- $failure"
|
||
|
|
done
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
echo ""
|
||
|
|
echo "[OK] Thirdweb account abstraction matrix is internally consistent."
|