Files
proxmox/scripts/verify/validate-address-registry-xe-aliases.mjs
defiQUG dbd517b279 Sync workspace: config, docs, scripts, CI, operator rules, and submodule pointers.
- 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
2026-04-12 06:12:20 -07:00

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)