Update asset registry for #68
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # .github/workflows/validate-registry.yml | |
| name: Validate Asset Registry | |
| on: | |
| pull_request: | |
| branches: [ main ] | |
| paths: | |
| - 'data/**' | |
| - 'schema/**' | |
| workflow_dispatch: | |
| jobs: | |
| validate-schema: | |
| name: Validate JSON Schema | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Install Node.js and tools | |
| run: | | |
| node --version | |
| npm --version | |
| npm install -g ajv-cli@5.0.0 | |
| npm install -g jsonlint@1.6.3 | |
| - name: Validate JSON syntax | |
| run: | | |
| echo "🔍 Validating JSON syntax..." | |
| # Check if mainnet directory exists | |
| if [ ! -d "data/mainnet" ]; then | |
| echo "❌ data/mainnet directory not found" | |
| exit 1 | |
| fi | |
| # Check if testnet directory exists | |
| if [ ! -d "data/testnet" ]; then | |
| echo "❌ data/testnet directory not found" | |
| exit 1 | |
| fi | |
| # Check if devnet directory exists | |
| if [ ! -d "data/devnet" ]; then | |
| echo "❌ data/devnet directory not found" | |
| exit 1 | |
| fi | |
| # Validate all mainnet JSON files | |
| echo "✅ Checking mainnet JSON files..." | |
| for file in data/mainnet/*.json; do | |
| if [ -f "$file" ]; then | |
| echo " Validating $(basename "$file")..." | |
| jsonlint "$file" | |
| fi | |
| done | |
| # Validate all testnet JSON files | |
| echo "✅ Checking testnet JSON files..." | |
| for file in data/testnet/*.json; do | |
| if [ -f "$file" ]; then | |
| echo " Validating $(basename "$file")..." | |
| jsonlint "$file" | |
| fi | |
| done | |
| # Validate all devnet JSON files | |
| echo "✅ Checking devnet JSON files..." | |
| for file in data/devnet/*.json; do | |
| if [ -f "$file" ]; then | |
| echo " Validating $(basename "$file")..." | |
| jsonlint "$file" | |
| fi | |
| done | |
| # Validate schema syntax | |
| if [ -f "schema/chain-asset.schema.json" ]; then | |
| echo "✅ Checking schema syntax..." | |
| jsonlint schema/chain-asset.schema.json | |
| else | |
| echo "❌ chain-asset.schema.json not found" | |
| exit 1 | |
| fi | |
| - name: Validate against JSON Schema | |
| run: | | |
| echo "🔍 Validating against JSON Schema..." | |
| # Validate all mainnet files against schema | |
| echo "✅ Validating mainnet files against schema..." | |
| for file in data/mainnet/*.json; do | |
| if [ -f "$file" ]; then | |
| echo " Validating $(basename "$file") against schema..." | |
| ajv validate \ | |
| --spec=draft7 \ | |
| --strict=false \ | |
| --all-errors \ | |
| -s schema/chain-asset.schema.json \ | |
| -d "$file" | |
| fi | |
| done | |
| # Validate all testnet files against schema | |
| echo "✅ Validating testnet files against schema..." | |
| for file in data/testnet/*.json; do | |
| if [ -f "$file" ]; then | |
| echo " Validating $(basename "$file") against schema..." | |
| ajv validate \ | |
| --spec=draft7 \ | |
| --strict=false \ | |
| --all-errors \ | |
| -s schema/chain-asset.schema.json \ | |
| -d "$file" | |
| fi | |
| done | |
| # Validate all devnet files against schema | |
| echo "✅ Validating devnet files against schema..." | |
| for file in data/devnet/*.json; do | |
| if [ -f "$file" ]; then | |
| echo " Validating $(basename "$file") against schema..." | |
| ajv validate \ | |
| --spec=draft7 \ | |
| --strict=false \ | |
| --all-errors \ | |
| -s schema/chain-asset.schema.json \ | |
| -d "$file" | |
| fi | |
| done | |
| - name: Validate business rules | |
| run: | | |
| echo "🔍 Validating business rules..." | |
| # Check for duplicate chain IDs across all networks | |
| echo "✅ Checking for duplicate chain IDs..." | |
| # Collect all chain IDs from mainnet | |
| MAINNET_CHAIN_IDS="" | |
| for file in data/mainnet/*.json; do | |
| if [ -f "$file" ]; then | |
| CHAIN_ID=$(jq -r '.chainId' "$file") | |
| MAINNET_CHAIN_IDS="$MAINNET_CHAIN_IDS $CHAIN_ID" | |
| fi | |
| done | |
| # Collect all chain IDs from testnet | |
| TESTNET_CHAIN_IDS="" | |
| for file in data/testnet/*.json; do | |
| if [ -f "$file" ]; then | |
| CHAIN_ID=$(jq -r '.chainId' "$file") | |
| TESTNET_CHAIN_IDS="$TESTNET_CHAIN_IDS $CHAIN_ID" | |
| fi | |
| done | |
| # Collect all chain IDs from devnet | |
| DEVNET_CHAIN_IDS="" | |
| for file in data/devnet/*.json; do | |
| if [ -f "$file" ]; then | |
| CHAIN_ID=$(jq -r '.chainId' "$file") | |
| DEVNET_CHAIN_IDS="$DEVNET_CHAIN_IDS $CHAIN_ID" | |
| fi | |
| done | |
| # Check for duplicates within mainnet | |
| MAINNET_DUPLICATES=$(echo $MAINNET_CHAIN_IDS | tr ' ' '\n' | sort | uniq -d) | |
| if [ ! -z "$MAINNET_DUPLICATES" ]; then | |
| echo "❌ Duplicate chain IDs found in mainnet: $MAINNET_DUPLICATES" | |
| exit 1 | |
| fi | |
| # Check for duplicates within testnet | |
| TESTNET_DUPLICATES=$(echo $TESTNET_CHAIN_IDS | tr ' ' '\n' | sort | uniq -d) | |
| if [ ! -z "$TESTNET_DUPLICATES" ]; then | |
| echo "❌ Duplicate chain IDs found in testnet: $TESTNET_DUPLICATES" | |
| exit 1 | |
| fi | |
| # Check for duplicates within devnet | |
| DEVNET_DUPLICATES=$(echo $DEVNET_CHAIN_IDS | tr ' ' '\n' | sort | uniq -d) | |
| if [ ! -z "$DEVNET_DUPLICATES" ]; then | |
| echo "❌ Duplicate chain IDs found in devnet: $DEVNET_DUPLICATES" | |
| exit 1 | |
| fi | |
| # Check that all RPC/REST URLs are reachable (optional) | |
| echo "✅ Checking URL accessibility..." | |
| # Test mainnet URLs | |
| for file in data/mainnet/*.json; do | |
| if [ -f "$file" ]; then | |
| CHAIN_NAME=$(basename "$file" .json) | |
| RPC_URL=$(jq -r '.rpcURL' "$file") | |
| echo "Testing $CHAIN_NAME mainnet RPC: $RPC_URL..." | |
| if ! curl -s --connect-timeout 10 --max-time 30 "$RPC_URL" > /dev/null; then | |
| echo "⚠️ Warning: $RPC_URL may not be accessible" | |
| fi | |
| fi | |
| done | |
| - name: Generate validation report | |
| if: always() | |
| run: | | |
| echo "📊 Validation Report" > validation-report.md | |
| echo "===================" >> validation-report.md | |
| echo "" >> validation-report.md | |
| echo "**Date:** $(date)" >> validation-report.md | |
| echo "**Commit:** ${{ github.sha }}" >> validation-report.md | |
| echo "" >> validation-report.md | |
| # Count chains by network | |
| MAINNET_COUNT=$(find data/mainnet -name "*.json" -type f | wc -l) | |
| TESTNET_COUNT=$(find data/testnet -name "*.json" -type f | wc -l) | |
| DEVNET_COUNT=$(find data/devnet -name "*.json" -type f | wc -l) | |
| echo "**Statistics:**" >> validation-report.md | |
| echo "- Mainnet chains: $MAINNET_COUNT" >> validation-report.md | |
| echo "- Testnet chains: $TESTNET_COUNT" >> validation-report.md | |
| echo "- Devnet chains: $DEVNET_COUNT" >> validation-report.md | |
| # Count total currencies | |
| MAINNET_CURRENCIES=0 | |
| for file in data/mainnet/*.json; do | |
| if [ -f "$file" ]; then | |
| COUNT=$(jq '[.currencies[]] | length' "$file") | |
| MAINNET_CURRENCIES=$((MAINNET_CURRENCIES + COUNT)) | |
| fi | |
| done | |
| TESTNET_CURRENCIES=0 | |
| for file in data/testnet/*.json; do | |
| if [ -f "$file" ]; then | |
| COUNT=$(jq '[.currencies[]] | length' "$file") | |
| TESTNET_CURRENCIES=$((TESTNET_CURRENCIES + COUNT)) | |
| fi | |
| done | |
| DEVNET_CURRENCIES=0 | |
| for file in data/devnet/*.json; do | |
| if [ -f "$file" ]; then | |
| COUNT=$(jq '[.currencies[]] | length' "$file") | |
| DEVNET_CURRENCIES=$((DEVNET_CURRENCIES + COUNT)) | |
| fi | |
| done | |
| echo "- Mainnet currencies: $MAINNET_CURRENCIES" >> validation-report.md | |
| echo "- Testnet currencies: $TESTNET_CURRENCIES" >> validation-report.md | |
| echo "- Devnet currencies: $DEVNET_CURRENCIES" >> validation-report.md | |
| echo "" >> validation-report.md | |
| echo "**Chain Status:**" >> validation-report.md | |
| echo "| Chain | Network | Chain ID | Currencies |" >> validation-report.md | |
| echo "|-------|---------|----------|------------|" >> validation-report.md | |
| # Mainnet chains | |
| for file in data/mainnet/*.json; do | |
| if [ -f "$file" ]; then | |
| CHAIN_NAME=$(basename "$file" .json) | |
| CHAIN_ID=$(jq -r '.chainId' "$file") | |
| CURRENCY_COUNT=$(jq '[.currencies[]] | length' "$file") | |
| echo "| $CHAIN_NAME | mainnet | $CHAIN_ID | $CURRENCY_COUNT |" >> validation-report.md | |
| fi | |
| done | |
| echo "" >> validation-report.md | |
| echo "| Chain | Network | Chain ID | Currencies |" >> validation-report.md | |
| echo "|-------|---------|----------|------------|" >> validation-report.md | |
| # Testnet chains | |
| for file in data/testnet/*.json; do | |
| if [ -f "$file" ]; then | |
| CHAIN_NAME=$(basename "$file" .json) | |
| CHAIN_ID=$(jq -r '.chainId' "$file") | |
| CURRENCY_COUNT=$(jq '[.currencies[]] | length' "$file") | |
| echo "| $CHAIN_NAME | testnet | $CHAIN_ID | $CURRENCY_COUNT |" >> validation-report.md | |
| fi | |
| done | |
| # Devnet chains | |
| echo "" >> validation-report.md | |
| echo "| Chain | Network | Chain ID | Currencies |" >> validation-report.md | |
| echo "|-------|---------|----------|------------|" >> validation-report.md | |
| for file in data/devnet/*.json; do | |
| if [ -f "$file" ]; then | |
| CHAIN_NAME=$(basename "$file" .json) | |
| CHAIN_ID=$(jq -r '.chainId' "$file") | |
| CURRENCY_COUNT=$(jq '[.currencies[]] | length' "$file") | |
| echo "| $CHAIN_NAME | devnet | $CHAIN_ID | $CURRENCY_COUNT |" >> validation-report.md | |
| fi | |
| done | |
| - name: Upload validation report | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: validation-report | |
| path: validation-report.md | |
| retention-days: 1 | |
| - name: Comment PR with validation results | |
| if: github.event_name == 'pull_request' | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const fs = require('fs'); | |
| try { | |
| const report = fs.readFileSync('validation-report.md', 'utf8'); | |
| await github.rest.issues.createComment({ | |
| issue_number: context.issue.number, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| body: `## 🔍 Registry Validation Report\n\n${report}` | |
| }); | |
| } catch (error) { | |
| console.log('Could not post comment:', error); | |
| } | |
| security-scan: | |
| name: Security Scan | |
| runs-on: ubuntu-latest | |
| needs: validate-schema | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Scan for sensitive data | |
| run: | | |
| echo "🔒 Scanning for sensitive data..." | |
| # Check for potential private keys or secrets | |
| if grep -r -i "private\|secret\|key\|password" data/ --exclude-dir=.git; then | |
| echo "⚠️ Warning: Potential sensitive data found" | |
| else | |
| echo "✅ No sensitive data detected" | |
| fi | |
| # Check for suspicious URLs or IPs | |
| if grep -r -E "(localhost|127\.0\.0\.1|192\.168\.|10\.|172\.)" data/; then | |
| echo "⚠️ Warning: Local/private network addresses found" | |
| else | |
| echo "✅ No local network addresses found" | |
| fi | |
| - name: Validate SSL certificates | |
| run: | | |
| echo "🔒 Validating SSL certificates..." | |
| # Extract HTTPS URLs and check certificates from all chain files | |
| for file in data/mainnet/*.json data/testnet/*.json data/devnet/*.json; do | |
| if [ -f "$file" ]; then | |
| NETWORK=$(basename $(dirname "$file")) | |
| CHAIN=$(basename "$file" .json) | |
| echo "Checking SSL certificates for $CHAIN ($NETWORK)..." | |
| jq -r '.rpcURL, .restURL' "$file" | \ | |
| grep -E '^https://' | \ | |
| while read url; do | |
| domain=$(echo "$url" | sed 's|https://||' | sed 's|:.*||' | sed 's|/.*||') | |
| echo " Checking SSL for $domain..." | |
| if ! echo | timeout 10 openssl s_client -connect "$domain:443" -servername "$domain" 2>/dev/null | grep -q "Verify return code: 0"; then | |
| echo " ⚠️ Warning: SSL certificate issue for $domain" | |
| fi | |
| done | |
| fi | |
| done | |
| performance-test: | |
| name: Performance Test | |
| runs-on: ubuntu-latest | |
| needs: validate-schema | |
| if: github.event_name == 'pull_request' | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Test endpoint response times | |
| run: | | |
| echo "⚡ Testing endpoint performance..." | |
| # Test RPC endpoints for all chains across all networks | |
| for file in data/mainnet/*.json data/testnet/*.json data/devnet/*.json; do | |
| if [ -f "$file" ]; then | |
| NETWORK=$(basename $(dirname "$file")) | |
| CHAIN_NAME=$(basename "$file" .json) | |
| RPC_URL=$(jq -r '.rpcURL' "$file") | |
| echo "Testing $CHAIN_NAME ($NETWORK) - $RPC_URL..." | |
| response_time=$(curl -w "%{time_total}" -s -o /dev/null --connect-timeout 10 --max-time 30 "$RPC_URL" || echo "timeout") | |
| if [ "$response_time" = "timeout" ]; then | |
| echo "❌ $CHAIN_NAME ($NETWORK): Timeout" | |
| elif (( $(echo "$response_time > 5.0" | bc -l) )); then | |
| echo "⚠️ $CHAIN_NAME ($NETWORK): Slow response (${response_time}s)" | |
| else | |
| echo "✅ $CHAIN_NAME ($NETWORK): Fast response (${response_time}s)" | |
| fi | |
| fi | |
| done | |
| - name: File size check | |
| run: | | |
| echo "📊 Checking file sizes..." | |
| # Check individual chain file sizes across all networks | |
| for file in data/mainnet/*.json data/testnet/*.json data/devnet/*.json; do | |
| if [ -f "$file" ]; then | |
| FILE_SIZE=$(stat -f%z "$file" 2>/dev/null || stat -c%s "$file") | |
| NETWORK=$(basename $(dirname "$file")) | |
| CHAIN_NAME=$(basename "$file") | |
| echo "$CHAIN_NAME ($NETWORK) size: ${FILE_SIZE} bytes" | |
| # Warn if individual files are getting too large (> 100KB) | |
| if [ "$FILE_SIZE" -gt 102400 ]; then | |
| echo "⚠️ Warning: $CHAIN_NAME ($NETWORK) is larger than 100KB" | |
| fi | |
| fi | |
| done |