1+ # .github/workflows/validate-registry.yml
2+ name : Validate Asset Registry
3+
4+ on :
5+ push :
6+ branches : [ main, develop ]
7+ paths :
8+ - ' data/**'
9+ - ' schema/**'
10+ pull_request :
11+ branches : [ main ]
12+ paths :
13+ - ' data/**'
14+ - ' schema/**'
15+ workflow_dispatch :
16+
17+ jobs :
18+ validate-schema :
19+ name : Validate JSON Schema
20+ runs-on : ubuntu-latest
21+
22+ steps :
23+ - name : Checkout repository
24+ uses : actions/checkout@v4
25+
26+ - name : Setup Node.js
27+ uses : actions/setup-node@v4
28+ with :
29+ node-version : ' 18'
30+ cache : ' npm'
31+
32+ - name : Install validation tools
33+ run : |
34+ npm install -g ajv-cli@5.0.0
35+ npm install -g jsonlint@1.6.3
36+
37+ - name : Validate JSON syntax
38+ run : |
39+ echo "🔍 Validating JSON syntax..."
40+
41+ # Validate mainnet.json syntax
42+ if [ -f "data/mainnet.json" ]; then
43+ echo "✅ Checking mainnet.json syntax..."
44+ jsonlint data/mainnet.json
45+ else
46+ echo "❌ mainnet.json not found"
47+ exit 1
48+ fi
49+
50+ # Validate testnet.json syntax
51+ if [ -f "data/testnet.json" ]; then
52+ echo "✅ Checking testnet.json syntax..."
53+ jsonlint data/testnet.json
54+ else
55+ echo "❌ testnet.json not found"
56+ exit 1
57+ fi
58+
59+ # Validate schema syntax
60+ if [ -f "schema/registry.schema.json" ]; then
61+ echo "✅ Checking schema syntax..."
62+ jsonlint schema/registry.schema.json
63+ else
64+ echo "❌ registry.schema.json not found"
65+ exit 1
66+ fi
67+
68+ - name : Validate against JSON Schema
69+ run : |
70+ echo "🔍 Validating against JSON Schema..."
71+
72+ # Validate mainnet.json against schema
73+ echo "✅ Validating mainnet.json against schema..."
74+ ajv validate \
75+ --spec=draft7 \
76+ --verbose \
77+ -s schema/registry.schema.json \
78+ -d data/mainnet.json
79+
80+ # Validate testnet.json against schema
81+ echo "✅ Validating testnet.json against schema..."
82+ ajv validate \
83+ --spec=draft7 \
84+ --verbose \
85+ -s schema/registry.schema.json \
86+ -d data/testnet.json
87+
88+ - name : Validate business rules
89+ run : |
90+ echo "🔍 Validating business rules..."
91+
92+ # Check for duplicate chain IDs across networks
93+ echo "✅ Checking for duplicate chain IDs..."
94+
95+ MAINNET_CHAIN_IDS=$(jq -r '.chains[].chainId' data/mainnet.json | sort)
96+ TESTNET_CHAIN_IDS=$(jq -r '.chains[].chainId' data/testnet.json | sort)
97+
98+ # Check for duplicates within mainnet
99+ MAINNET_DUPLICATES=$(echo "$MAINNET_CHAIN_IDS" | uniq -d)
100+ if [ ! -z "$MAINNET_DUPLICATES" ]; then
101+ echo "❌ Duplicate chain IDs found in mainnet: $MAINNET_DUPLICATES"
102+ exit 1
103+ fi
104+
105+ # Check for duplicates within testnet
106+ TESTNET_DUPLICATES=$(echo "$TESTNET_CHAIN_IDS" | uniq -d)
107+ if [ ! -z "$TESTNET_DUPLICATES" ]; then
108+ echo "❌ Duplicate chain IDs found in testnet: $TESTNET_DUPLICATES"
109+ exit 1
110+ fi
111+
112+ # Check that all RPC/REST URLs are reachable (optional)
113+ echo "✅ Checking URL accessibility..."
114+
115+ # Extract and test mainnet URLs
116+ jq -r '.chains[] | "\(.rpcURL) \(.restURL)"' data/mainnet.json | while read rpc rest; do
117+ echo "Testing $rpc..."
118+ if ! curl -s --connect-timeout 10 --max-time 30 "$rpc" > /dev/null; then
119+ echo "⚠️ Warning: $rpc may not be accessible"
120+ fi
121+ done
122+
123+ - name : Generate validation report
124+ if : always()
125+ run : |
126+ echo "📊 Validation Report" > validation-report.md
127+ echo "===================" >> validation-report.md
128+ echo "" >> validation-report.md
129+ echo "**Date:** $(date)" >> validation-report.md
130+ echo "**Commit:** ${{ github.sha }}" >> validation-report.md
131+ echo "" >> validation-report.md
132+
133+ # Count assets
134+ MAINNET_COUNT=$(jq '.chains | length' data/mainnet.json)
135+ TESTNET_COUNT=$(jq '.chains | length' data/testnet.json)
136+
137+ echo "**Statistics:**" >> validation-report.md
138+ echo "- Mainnet chains: $MAINNET_COUNT" >> validation-report.md
139+ echo "- Testnet chains: $TESTNET_COUNT" >> validation-report.md
140+
141+ # Count currencies
142+ MAINNET_CURRENCIES=$(jq '[.chains[].currencies[]] | length' data/mainnet.json)
143+ TESTNET_CURRENCIES=$(jq '[.chains[].currencies[]] | length' data/testnet.json)
144+
145+ echo "- Mainnet currencies: $MAINNET_CURRENCIES" >> validation-report.md
146+ echo "- Testnet currencies: $TESTNET_CURRENCIES" >> validation-report.md
147+ echo "" >> validation-report.md
148+
149+ echo "**Chain Status:**" >> validation-report.md
150+ echo "| Chain | Network | Enabled | Priority |" >> validation-report.md
151+ echo "|-------|---------|---------|----------|" >> validation-report.md
152+
153+ # Mainnet chains
154+ jq -r '.chains | to_entries[] | "| \(.key) | mainnet | \(.value.isEnabled) | \(.value.priority) |"' data/mainnet.json >> validation-report.md
155+
156+ # Testnet chains
157+ jq -r '.chains | to_entries[] | "| \(.key) | testnet | \(.value.isEnabled) | \(.value.priority) |"' data/testnet.json >> validation-report.md
158+
159+ - name : Upload validation report
160+ if : always()
161+ uses : actions/upload-artifact@v4
162+ with :
163+ name : validation-report
164+ path : validation-report.md
165+ retention-days : 30
166+
167+ - name : Comment PR with validation results
168+ if : github.event_name == 'pull_request'
169+ uses : actions/github-script@v7
170+ with :
171+ script : |
172+ const fs = require('fs');
173+
174+ try {
175+ const report = fs.readFileSync('validation-report.md', 'utf8');
176+
177+ await github.rest.issues.createComment({
178+ issue_number: context.issue.number,
179+ owner: context.repo.owner,
180+ repo: context.repo.repo,
181+ body: `## 🔍 Registry Validation Report\n\n${report}`
182+ });
183+ } catch (error) {
184+ console.log('Could not post comment:', error);
185+ }
186+
187+ security-scan :
188+ name : Security Scan
189+ runs-on : ubuntu-latest
190+ needs : validate-schema
191+
192+ steps :
193+ - name : Checkout repository
194+ uses : actions/checkout@v4
195+
196+ - name : Scan for sensitive data
197+ run : |
198+ echo "🔒 Scanning for sensitive data..."
199+
200+ # Check for potential private keys or secrets
201+ if grep -r -i "private\|secret\|key\|password" data/ --exclude-dir=.git; then
202+ echo "⚠️ Warning: Potential sensitive data found"
203+ else
204+ echo "✅ No sensitive data detected"
205+ fi
206+
207+ # Check for suspicious URLs or IPs
208+ if grep -r -E "(localhost|127\.0\.0\.1|192\.168\.|10\.|172\.)" data/; then
209+ echo "⚠️ Warning: Local/private network addresses found"
210+ else
211+ echo "✅ No local network addresses found"
212+ fi
213+
214+ - name : Validate SSL certificates
215+ run : |
216+ echo "🔒 Validating SSL certificates..."
217+
218+ # Extract HTTPS URLs and check certificates
219+ jq -r '.chains[] | "\(.rpcURL) \(.restURL)"' data/mainnet.json | \
220+ grep -E '^https://' | \
221+ while read url; do
222+ domain=$(echo "$url" | sed 's|https://||' | sed 's|:.*||')
223+ echo "Checking SSL for $domain..."
224+
225+ if ! echo | timeout 10 openssl s_client -connect "$domain:443" -servername "$domain" 2>/dev/null | grep -q "Verify return code: 0"; then
226+ echo "⚠️ Warning: SSL certificate issue for $domain"
227+ fi
228+ done
229+
230+ performance-test :
231+ name : Performance Test
232+ runs-on : ubuntu-latest
233+ needs : validate-schema
234+ if : github.event_name == 'pull_request'
235+
236+ steps :
237+ - name : Checkout repository
238+ uses : actions/checkout@v4
239+
240+ - name : Test endpoint response times
241+ run : |
242+ echo "⚡ Testing endpoint performance..."
243+
244+ # Test RPC endpoints
245+ jq -r '.chains[] | "\(.chainName): \(.rpcURL)"' data/mainnet.json | while IFS=': ' read name url; do
246+ echo "Testing $name ($url)..."
247+
248+ response_time=$(curl -w "%{time_total}" -s -o /dev/null --connect-timeout 10 --max-time 30 "$url" || echo "timeout")
249+
250+ if [ "$response_time" = "timeout" ]; then
251+ echo "❌ $name: Timeout"
252+ elif (( $(echo "$response_time > 5.0" | bc -l) )); then
253+ echo "⚠️ $name: Slow response (${response_time}s)"
254+ else
255+ echo "✅ $name: Fast response (${response_time}s)"
256+ fi
257+ done
258+
259+ - name : File size check
260+ run : |
261+ echo "📊 Checking file sizes..."
262+
263+ MAINNET_SIZE=$(stat -f%z data/mainnet.json 2>/dev/null || stat -c%s data/mainnet.json)
264+ TESTNET_SIZE=$(stat -f%z data/testnet.json 2>/dev/null || stat -c%s data/testnet.json)
265+
266+ echo "Mainnet.json size: ${MAINNET_SIZE} bytes"
267+ echo "Testnet.json size: ${TESTNET_SIZE} bytes"
268+
269+ # Warn if files are getting too large (> 1MB)
270+ if [ "$MAINNET_SIZE" -gt 1048576 ]; then
271+ echo "⚠️ Warning: mainnet.json is larger than 1MB"
272+ fi
273+
274+ if [ "$TESTNET_SIZE" -gt 1048576 ]; then
275+ echo "⚠️ Warning: testnet.json is larger than 1MB"
276+ fi
0 commit comments