- Update dbis_core, cross-chain-pmm-lps, explorer-monorepo, metamask-integration, pr-workspace/chains - Omit embedded publish git dirs and empty placeholders from index Made-with: Cursor
112 lines
3.4 KiB
JavaScript
112 lines
3.4 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Validate address-registry JSON: each alias with aliasType "web3_eth_iban" must be a valid
|
|
* XE… direct/indirect IBAN per web3-eth-iban; if toAddress() succeeds, it must match entry.address.
|
|
*
|
|
* Usage:
|
|
* node scripts/verify/validate-address-registry-xe-aliases.mjs [path/to/registry.json ...]
|
|
* (no args: validates repo examples under config/dbis-institutional/examples/)
|
|
*/
|
|
import { createRequire } from 'module'
|
|
import { readFileSync, existsSync } from 'fs'
|
|
import { resolve, dirname, join } from 'path'
|
|
import { fileURLToPath } from 'url'
|
|
|
|
const require = createRequire(import.meta.url)
|
|
const Iban = require('web3-eth-iban')
|
|
|
|
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
const ROOT = resolve(__dirname, '../..')
|
|
const DEFAULT_FILES = [
|
|
join(ROOT, 'config/dbis-institutional/examples/address-registry-entry.example.json'),
|
|
join(ROOT, 'config/dbis-institutional/examples/address-registry-entries-batch.example.json'),
|
|
]
|
|
|
|
function normalizeAddr(a) {
|
|
if (typeof a !== 'string' || !/^0x[a-fA-F0-9]{40}$/.test(a)) return null
|
|
return a.toLowerCase()
|
|
}
|
|
|
|
function collectEntries(data) {
|
|
if (Array.isArray(data)) return data
|
|
if (data && typeof data === 'object') return [data]
|
|
return []
|
|
}
|
|
|
|
function validateEntry(entry, sourceLabel) {
|
|
const id = entry.registryEntryId || sourceLabel
|
|
const addr = normalizeAddr(entry.address)
|
|
if (!addr) {
|
|
console.error(`FAIL ${id}: missing or invalid address`)
|
|
return 1
|
|
}
|
|
const aliases = entry.aliases
|
|
if (!Array.isArray(aliases)) return 0
|
|
|
|
let errors = 0
|
|
for (const al of aliases) {
|
|
if (!al || al.aliasType !== 'web3_eth_iban') continue
|
|
const raw = al.aliasValue
|
|
if (typeof raw !== 'string' || !raw.trim()) {
|
|
console.error(`FAIL ${id}: web3_eth_iban aliasValue must be a non-empty string`)
|
|
errors++
|
|
continue
|
|
}
|
|
const ibanStr = raw.trim().toUpperCase()
|
|
if (!Iban.isValid(ibanStr)) {
|
|
console.error(`FAIL ${id}: invalid XE/Ethereum IBAN checksum or format: ${raw}`)
|
|
errors++
|
|
continue
|
|
}
|
|
try {
|
|
const resolved = Iban.toAddress(ibanStr)
|
|
const resolvedNorm = normalizeAddr(resolved)
|
|
if (resolvedNorm && resolvedNorm !== addr) {
|
|
console.error(
|
|
`FAIL ${id}: web3_eth_iban ${ibanStr} resolves to ${resolved}, expected ${entry.address}`,
|
|
)
|
|
errors++
|
|
}
|
|
} catch {
|
|
// web3-eth-iban toAddress() throws on some leading-zero encodings; checksum validity still enforced above.
|
|
console.warn(
|
|
`WARN ${id}: IBAN ${ibanStr} is valid but toAddress() failed (library edge case); verify manually against ${entry.address}`,
|
|
)
|
|
}
|
|
}
|
|
return errors
|
|
}
|
|
|
|
function validateFile(filePath) {
|
|
const abs = resolve(filePath)
|
|
if (!existsSync(abs)) {
|
|
console.error(`Missing file: ${abs}`)
|
|
return 1
|
|
}
|
|
let data
|
|
try {
|
|
data = JSON.parse(readFileSync(abs, 'utf8'))
|
|
} catch (e) {
|
|
console.error(`Invalid JSON: ${abs}`, e.message)
|
|
return 1
|
|
}
|
|
let total = 0
|
|
for (const entry of collectEntries(data)) {
|
|
total += validateEntry(entry, abs)
|
|
}
|
|
if (total === 0) {
|
|
console.log(`OK XE/web3_eth_iban aliases: ${abs}`)
|
|
}
|
|
return total
|
|
}
|
|
|
|
const paths = process.argv.slice(2).filter((a) => !a.startsWith('-'))
|
|
const targets = paths.length > 0 ? paths : DEFAULT_FILES
|
|
|
|
let exitCode = 0
|
|
for (const p of targets) {
|
|
const code = validateFile(p)
|
|
if (code !== 0) exitCode = 1
|
|
}
|
|
process.exit(exitCode)
|