Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check and validate JSON schema #1509

Merged
merged 13 commits into from
Aug 28, 2022
24 changes: 24 additions & 0 deletions .github/workflows/validate_json.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Check JSON Schema

on:
push:
pull_request:

jobs:
validate_json:
runs-on: ubuntu-latest
steps:
- name: Check out repo
uses: actions/checkout@v2
- uses: actions/cache@v2
name: Configure npm caching
with:
path: ~/.npm
key: ${{ runner.os }}-npm-${{ hashFiles('**/workflows/validate_json.yml') }}
restore-keys: |
${{ runner.os }}-npm-
- name: Run JSON Validation
working-directory: ./tools
run: |-
npm install
node schemaCheck.js
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ The source data is in _data/chains. Each chain has its own file with the filenam
{
"name": "Ethereum Mainnet",
"chain": "ETH",
"network": "mainnet",
"rpc": [
"https://mainnet.infura.io/v3/${INFURA_API_KEY}",
"https://api.mycryptoapi.com/eth"
Expand Down
114 changes: 114 additions & 0 deletions tools/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions tools/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"devDependencies": {
"ajv": "^8.11.0"
}
}
12 changes: 7 additions & 5 deletions tools/index.js → tools/rmNetwork.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@
* This removed `network` param from all the chain files
* Since this is the only tool here, it is here in index.js
*/

const fs = require('fs');
const { exec } = require('child_process');
const chainFiles = fs.readdirSync('../_data/chains/');

for(const chainFile of chainFiles){
for (const chainFile of chainFiles) {
const fileLocation = `../_data/chains/${chainFile}`
const fileData = fs.readFileSync(fileLocation,'utf8')
const fileData = fs.readFileSync(fileLocation, 'utf8')
const fileDataJson = JSON.parse(fileData)
if(fileDataJson.network){

if (fileDataJson.network) {
delete fileDataJson.network
fs.writeFileSync(fileLocation, JSON.stringify(fileDataJson, null, 2))
}
}

// TODO: Run `npx prettier --write --ignore-unknown _data`from Project Directory
// Note:
// Run `npx prettier --write --ignore-unknown _data`from Project Directory
123 changes: 123 additions & 0 deletions tools/schema/chainSchema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
{
"$schema": "http://json-schema.org/schema#",
"title": "EIP155 Chain Data",
"type":"object",
"required": ["name","shortName","chain","chainId","networkId","rpc","faucets","infoURL","nativeCurrency"],
"properties": {
"name":{
"type":"string",
"description": "Name of the Network"
},
"shortName":{
"type":"string"
},
"title":{
"type":"string",
"description": "Optional title for the Network"
},
"chain":{
"type":"string",
"description": "Name of the Network"
},
"icon":{
"type":"string",
"description": "Icon type"
},
"rpc":{
"type":"array",
"items":{
"type":"string"
}
},
"faucets":{
"type":"array",
"items":{
"type":"string"
}
},
"nativeCurrency":{
"type":"object",
"properties": {
"name":{
"type":"string",
"description":"Name of the Native Currency"
},
"symbol":{
"type":"string",
"description":"Symbol of the Native Currency"
},
"decimals":{
"type":"number",
"description":"Decimal points supported"
}
}
},
"infoURL":{
"type":"string",
"description": "infoURL"
},
"chainId":{
"type":"number",
"description": "Chain ID of the Network"
},
"networkId":{
"type":"number",
"description": "Network ID of the Network"
},
"slip44":{
"type":"number",
"description": "Slip44 of the Network"
},
"ens":{
"type":"object",
"properties": {
"registry":{
"type":"string"
}
}
},
"explorers":{
"type":"array",
"items":{
"type":"object",
"properties": {
"name":{
"type":"string"
},
"url":{
"type":"string"
},
"standard":{
"type":"string"
}
}
}
},
"parent":{
"type":"object",
"properties": {
"type":{
"type":"string"
},
"chain":{
"type":"string"
},
"bridges":{
"type":"array",
"items": {
"type":"object",
"properties":{
"url": {
"type":"string"
}
}
}
}
}
},
"status":{
"type":"string"
}
},
"additionalProperties": false
}
25 changes: 25 additions & 0 deletions tools/schemaCheck.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const fs = require('fs');
const Ajv = require("ajv")
const ajv = new Ajv()
const schema = require('./schema/chainSchema.json')
const chainFiles = fs.readdirSync('../_data/chains/');

const filesWithErrors = []
for(const chainFile of chainFiles){
const fileLocation = `../_data/chains/${chainFile}`
const fileData = fs.readFileSync(fileLocation,'utf8')
const fileDataJson = JSON.parse(fileData)
const chainIdFromFileName = chainFile.match(/eip155-(\d+)\.json/)[1]
if(chainIdFromFileName != fileDataJson.chainId){
throw new Error(`File Name does not match with ChainID in ${chainFile}`)
}
const valid = ajv.validate(schema, fileDataJson)
if(!valid) {
console.error(ajv.errors)
filesWithErrors.push(chainFile)
}
}

if(filesWithErrors.length > 0){
throw new Error(`Invalid JSON Schema in ${filesWithErrors.length} files at ${filesWithErrors.join(",")}`)
}