feat(omnl): HYBX-BATCH-001 package, rail scripts, regulatory docs, CI
Some checks failed
Deploy to Phoenix / deploy (push) Has been cancelled

- Add OMNL/CBK Indonesia submission and audit binder docs, manifests, attestations
- Add scripts/omnl transaction-package pipeline, LEI/PvP helpers, jq/lib fixtures
- Update entity master data, MASTER_INDEX, TODOS, dbis-rail docs and rulebook
- Add proof_package/regulatory skeleton and transaction package zip + snapshot JSON
- validate-omnl-rail workflow, forge-verification-proxy tweak, .gitignore hygiene
- Bump smom-dbis-138 (cronos verify docs/scripts) and explorer-monorepo (SPA + env report)

Made-with: Cursor
This commit is contained in:
defiQUG
2026-03-24 18:11:36 -07:00
parent bfb8b321c0
commit 95522d3bca
64 changed files with 4048 additions and 75 deletions

View File

@@ -63,7 +63,14 @@ function send(res, status, data) {
async function forwardEtherscanFormat(payload) {
const query = new URLSearchParams({ module: 'contract', action: 'verifysourcecode' });
const path = `/api/?${query}`;
const body = JSON.stringify(payload);
// Blockscout's Etherscan-compatible endpoint expects classic form fields, not JSON.
// Keep the Forge payload keys, but serialize them as application/x-www-form-urlencoded.
const form = new URLSearchParams();
for (const [key, value] of Object.entries(payload)) {
if (value === undefined || value === null || value === '') continue;
form.set(key, String(value));
}
const body = form.toString();
const url = new URL(path, BLOCKSCOUT_URL);
return new Promise((resolve, reject) => {
@@ -74,7 +81,7 @@ async function forwardEtherscanFormat(payload) {
path: url.pathname + url.search,
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(body),
Host: url.hostname + (url.port ? ':' + url.port : ''),
},
@@ -98,7 +105,7 @@ async function forwardEtherscanFormat(payload) {
}
/**
* Forward to Blockscout v2 flattened-code API (for Standard JSON, we pass as source_code).
* Forward to Blockscout v2 flattened-code verification API.
*/
async function forwardV2Flattened(payload) {
const addr = payload.contractaddress || payload.contractAddress;
@@ -157,6 +164,90 @@ async function forwardV2Flattened(payload) {
});
}
/**
* Forward to Blockscout v2 verification API for Standard JSON input.
*/
async function forwardV2StandardInput(payload) {
const addr = payload.contractaddress || payload.contractAddress;
const sourceCode = payload.sourceCode ?? payload.source_code;
const standardJson =
typeof sourceCode === 'string'
? sourceCode
: JSON.stringify(sourceCode);
const path = `/api/v2/smart-contracts/${addr}/verification/via/standard-input`;
const boundary = `----forge-verification-proxy-${Math.random().toString(16).slice(2)}`;
const parts = [];
const appendField = (name, value) => {
if (value === undefined || value === null || value === '') return;
parts.push(Buffer.from(`--${boundary}\r\n`));
parts.push(Buffer.from(`Content-Disposition: form-data; name="${name}"\r\n\r\n`));
parts.push(Buffer.from(`${value}\r\n`));
};
const appendFile = (name, filename, content, contentType = 'application/json') => {
parts.push(Buffer.from(`--${boundary}\r\n`));
parts.push(Buffer.from(`Content-Disposition: form-data; name="${name}"; filename="${filename}"\r\n`));
parts.push(Buffer.from(`Content-Type: ${contentType}\r\n\r\n`));
parts.push(Buffer.isBuffer(content) ? content : Buffer.from(String(content)));
parts.push(Buffer.from('\r\n'));
};
const compilerVersion = payload.compilerversion || payload.compilerVersion || 'v0.8.20+commit.a1b79de6';
const contractName = payload.contractname || payload.contractName || 'Contract';
const licenseType = payload.licensetype || payload.licenseType || 'mit';
const constructorArgs =
payload.constructor_args ??
payload.constructorArguments ??
payload.constructorArgumentsHex ??
payload.constructorArgs ??
'';
appendField('compiler_version', compilerVersion);
appendField('contract_name', contractName);
appendField('autodetect_constructor_args', String(payload.autodetectConstructorArguments !== false));
appendField('license_type', licenseType);
appendField('constructor_args', constructorArgs);
if (payload.evmversion || payload.evm_version) appendField('evm_version', payload.evmversion || payload.evm_version);
if (payload.optimizationUsed !== undefined || payload.optimization_used !== undefined) {
appendField('is_optimization_enabled', String([true, '1', 1, 'true'].includes(payload.optimizationUsed ?? payload.optimization_used)));
}
if (payload.runs !== undefined || payload.optimization_runs !== undefined) {
appendField('optimization_runs', String(parseInt(payload.runs ?? payload.optimization_runs ?? '200', 10) || 200));
}
appendFile('files[0]', 'standard-input.json', standardJson, 'application/json');
parts.push(Buffer.from(`--${boundary}--\r\n`));
const body = Buffer.concat(parts);
const url = new URL(path, BLOCKSCOUT_URL);
return new Promise((resolve, reject) => {
const req = http.request(
{
hostname: url.hostname,
port: url.port || (url.protocol === 'https:' ? 443 : 80),
path: url.pathname,
method: 'POST',
headers: {
'Content-Type': `multipart/form-data; boundary=${boundary}`,
'Content-Length': body.length,
},
},
(res) => {
let data = '';
res.on('data', (chunk) => { data += chunk; });
res.on('end', () => {
try {
resolve({ status: res.statusCode, data: data ? JSON.parse(data) : {}, raw: data });
} catch {
resolve({ status: res.statusCode, data: null, raw: data });
}
});
}
);
req.on('error', reject);
req.write(body);
req.end();
});
}
function toEtherscanResponse(result) {
const { status, data, raw } = result;
if (status >= 200 && status < 300 && data?.status === '1') {
@@ -261,7 +352,7 @@ const server = http.createServer(async (req, res) => {
codeformat === 'solidity-standard-json-input' ||
(typeof sourceCode === 'string' && sourceCode.trimStart().startsWith('{') && sourceCode.includes('"sources"'));
// Etherscan API expects Standard JSON in sourceCode; flattened Solidity causes "Invalid JSON".
// Try v2 API first for flattened code; use Etherscan only for Standard JSON.
// Try v2 API first for flattened code; use multipart standard-input when the payload is Standard JSON.
const tryV2First = !isStandardJson;
try {
@@ -278,13 +369,13 @@ const server = http.createServer(async (req, res) => {
return;
}
} else {
result = await forwardEtherscanFormat(payload);
result = await forwardV2StandardInput(payload);
out = toEtherscanResponse(result);
if (out.status !== '1') {
console.error('[forge-verification-proxy] Etherscan API failed:', out.message, '- trying v2...');
result = await forwardV2Flattened(payload);
const v2Out = toEtherscanResponse(result);
send(res, 200, v2Out);
console.error('[forge-verification-proxy] v2 standard-input failed:', out.message, '- trying Etherscan format...');
result = await forwardEtherscanFormat(payload);
const etherOut = toEtherscanResponse(result);
send(res, 200, etherOut.status === '1' ? etherOut : out);
return;
}
}