- 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
314 lines
12 KiB
JavaScript
314 lines
12 KiB
JavaScript
#!/usr/bin/env node
|
||
|
||
import fs from 'fs';
|
||
import path from 'path';
|
||
|
||
const repoRoot = path.resolve(path.dirname(new URL(import.meta.url).pathname), '..', '..');
|
||
const smartContractsPath = path.join(repoRoot, 'config', 'smart-contracts-master.json');
|
||
const deploymentStatusPath = path.join(repoRoot, 'cross-chain-pmm-lps', 'config', 'deployment-status.json');
|
||
const outputJsonPath = path.join(repoRoot, 'reports', 'status', 'contract_verification_publish_matrix.json');
|
||
const outputMdPath = path.join(repoRoot, 'docs', '11-references', 'CONTRACT_VERIFICATION_AND_PUBLICATION_MATRIX_ALL_NETWORKS.md');
|
||
|
||
const CHAIN_META = {
|
||
'1': {
|
||
name: 'Ethereum Mainnet',
|
||
explorer: 'https://etherscan.io',
|
||
verifierKind: 'etherscan',
|
||
publishSurface: 'Etherscan + repo inventory/token maps',
|
||
},
|
||
'10': {
|
||
name: 'Optimism',
|
||
explorer: 'https://optimistic.etherscan.io',
|
||
verifierKind: 'etherscan-family',
|
||
publishSurface: 'Optimism explorer + repo inventory/token maps',
|
||
},
|
||
'25': {
|
||
name: 'Cronos',
|
||
explorer: 'https://cronoscan.com',
|
||
verifierKind: 'etherscan-family',
|
||
publishSurface: 'Cronoscan + repo inventory/token maps',
|
||
},
|
||
'56': {
|
||
name: 'BSC',
|
||
explorer: 'https://bscscan.com',
|
||
verifierKind: 'etherscan-family',
|
||
publishSurface: 'BscScan + repo inventory/token maps',
|
||
},
|
||
'100': {
|
||
name: 'Gnosis',
|
||
explorer: 'https://gnosisscan.io',
|
||
verifierKind: 'etherscan-family',
|
||
publishSurface: 'Gnosis explorer + repo inventory/token maps',
|
||
},
|
||
'1111': {
|
||
name: 'Wemix',
|
||
explorer: 'https://explorer.wemix.com',
|
||
verifierKind: 'manual',
|
||
publishSurface: 'Wemix explorer + repo inventory/token maps',
|
||
},
|
||
'137': {
|
||
name: 'Polygon',
|
||
explorer: 'https://polygonscan.com',
|
||
verifierKind: 'etherscan-family',
|
||
publishSurface: 'PolygonScan + repo inventory/token maps',
|
||
},
|
||
'138': {
|
||
name: 'Chain 138',
|
||
explorer: 'https://blockscout.defi-oracle.io',
|
||
explorerAlt: 'https://explorer.d-bis.org',
|
||
verifierKind: 'blockscout',
|
||
publishSurface: 'Blockscout + repo inventory + explorer token/config surfaces',
|
||
verificationScript: 'bash scripts/verify/run-contract-verification-with-proxy.sh',
|
||
},
|
||
'42161': {
|
||
name: 'Arbitrum',
|
||
explorer: 'https://arbiscan.io',
|
||
verifierKind: 'etherscan-family',
|
||
publishSurface: 'Arbiscan + repo inventory/token maps',
|
||
},
|
||
'42220': {
|
||
name: 'Celo',
|
||
explorer: 'https://celoscan.io',
|
||
verifierKind: 'etherscan-family',
|
||
publishSurface: 'Celo explorer + repo inventory/token maps',
|
||
},
|
||
'43114': {
|
||
name: 'Avalanche',
|
||
explorer: 'https://snowtrace.io',
|
||
verifierKind: 'etherscan-family',
|
||
publishSurface: 'Snowtrace + repo inventory/token maps',
|
||
},
|
||
'8453': {
|
||
name: 'Base',
|
||
explorer: 'https://basescan.org',
|
||
verifierKind: 'etherscan-family',
|
||
publishSurface: 'Basescan + repo inventory/token maps',
|
||
},
|
||
'651940': {
|
||
name: 'ALL Mainnet',
|
||
explorer: 'https://alltra.global',
|
||
verifierKind: 'manual',
|
||
publishSurface: 'Alltra explorer/docs + repo inventory/token maps',
|
||
},
|
||
};
|
||
|
||
function loadJson(filePath) {
|
||
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
||
}
|
||
|
||
function ensureDir(filePath) {
|
||
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
||
}
|
||
|
||
function chainMeta(chainId, fallbackName = '') {
|
||
const meta = CHAIN_META[String(chainId)] || {};
|
||
return {
|
||
chainId: String(chainId),
|
||
chainName: meta.name || fallbackName || `Chain ${chainId}`,
|
||
explorer: meta.explorer || '',
|
||
explorerAlt: meta.explorerAlt || '',
|
||
verifierKind: meta.verifierKind || 'manual',
|
||
publishSurface: meta.publishSurface || 'Explorer + repo inventory',
|
||
verificationScript: meta.verificationScript || '',
|
||
};
|
||
}
|
||
|
||
function pushEntry(target, entry) {
|
||
target.push({
|
||
verificationStatus: 'pending',
|
||
publicationStatus: 'pending',
|
||
publishRequirement: 'Verify source on chain explorer and keep repo inventories/token maps aligned',
|
||
...entry,
|
||
});
|
||
}
|
||
|
||
const smartContracts = loadJson(smartContractsPath);
|
||
const deploymentStatus = loadJson(deploymentStatusPath);
|
||
|
||
const entries = [];
|
||
|
||
for (const [chainId, chainData] of Object.entries(smartContracts.chains || {})) {
|
||
const meta = chainMeta(chainId);
|
||
for (const [label, address] of Object.entries(chainData.contracts || {})) {
|
||
pushEntry(entries, {
|
||
sourceRegistry: 'config/smart-contracts-master.json',
|
||
contractType: 'canonical_contract',
|
||
label,
|
||
address,
|
||
...meta,
|
||
automation: chainId === '138' ? 'repo-supported' : 'manual-or-external',
|
||
publishNotes: chainId === '138'
|
||
? 'Canonical Chain 138 contract; verify in Blockscout and keep reference docs current'
|
||
: 'Mainnet relay or non-138 canonical contract; verify on chain explorer and mirror in repo docs',
|
||
});
|
||
}
|
||
}
|
||
|
||
for (const [chainId, chainData] of Object.entries(deploymentStatus.chains || {})) {
|
||
const meta = chainMeta(chainId, chainData.name);
|
||
for (const [label, address] of Object.entries(chainData.cwTokens || {})) {
|
||
pushEntry(entries, {
|
||
sourceRegistry: 'cross-chain-pmm-lps/config/deployment-status.json',
|
||
contractType: 'cw_token',
|
||
label,
|
||
address,
|
||
...meta,
|
||
automation: 'inventory-only',
|
||
publishNotes: 'Cross-chain wrapped/canonical token; verify on explorer and keep PMM/token-mapping inventories aligned',
|
||
});
|
||
}
|
||
for (const [label, address] of Object.entries(chainData.gasMirrors || {})) {
|
||
pushEntry(entries, {
|
||
sourceRegistry: 'cross-chain-pmm-lps/config/deployment-status.json',
|
||
contractType: 'gas_mirror',
|
||
label,
|
||
address,
|
||
...meta,
|
||
automation: 'inventory-only',
|
||
publishNotes: 'Gas-family mirror token; verify on explorer and keep gas rollout inventory aligned',
|
||
});
|
||
}
|
||
for (const [label, address] of Object.entries(chainData.anchorAddresses || {})) {
|
||
pushEntry(entries, {
|
||
sourceRegistry: 'cross-chain-pmm-lps/config/deployment-status.json',
|
||
contractType: 'anchor_token',
|
||
label,
|
||
address,
|
||
...meta,
|
||
automation: 'reference-only',
|
||
publishNotes: 'Anchor/reference asset; confirm explorer address and keep mapping docs current',
|
||
});
|
||
}
|
||
for (const pool of chainData.pmmPools || []) {
|
||
pushEntry(entries, {
|
||
sourceRegistry: 'cross-chain-pmm-lps/config/deployment-status.json',
|
||
contractType: 'pmm_pool',
|
||
label: `${pool.base}/${pool.quote}`,
|
||
address: pool.poolAddress,
|
||
...meta,
|
||
automation: chainId === '138' ? 'partial' : 'inventory-only',
|
||
publishNotes: `PMM pool (${pool.role || 'unclassified'}); verify source if custom deployment and keep routing inventory aligned`,
|
||
});
|
||
}
|
||
for (const pool of chainData.pmmPoolsVolatile || []) {
|
||
pushEntry(entries, {
|
||
sourceRegistry: 'cross-chain-pmm-lps/config/deployment-status.json',
|
||
contractType: 'pmm_pool_volatile',
|
||
label: `${pool.base}/${pool.quote}`,
|
||
address: pool.poolAddress,
|
||
...meta,
|
||
automation: 'inventory-only',
|
||
publishNotes: `Volatile PMM pool (${pool.role || 'unclassified'}); verify source where repo owns deployment and keep routing inventory aligned`,
|
||
});
|
||
}
|
||
for (const venue of chainData.gasReferenceVenues || []) {
|
||
if (!venue.venueAddress) continue;
|
||
pushEntry(entries, {
|
||
sourceRegistry: 'cross-chain-pmm-lps/config/deployment-status.json',
|
||
contractType: 'reference_venue',
|
||
label: `${venue.protocol}:${venue.base}/${venue.quote}`,
|
||
address: venue.venueAddress,
|
||
...meta,
|
||
automation: 'inventory-only',
|
||
publishNotes: 'Reference venue entry; verify only if repo owns deployment, otherwise treat as external dependency',
|
||
});
|
||
}
|
||
}
|
||
|
||
entries.sort((a, b) => {
|
||
if (a.chainId !== b.chainId) return Number(a.chainId) - Number(b.chainId);
|
||
if (a.contractType !== b.contractType) return a.contractType.localeCompare(b.contractType);
|
||
return a.label.localeCompare(b.label);
|
||
});
|
||
|
||
const summaryByChain = new Map();
|
||
for (const entry of entries) {
|
||
const key = `${entry.chainId}:${entry.chainName}`;
|
||
const current = summaryByChain.get(key) || { total: 0, canonical: 0, cw: 0, pools: 0 };
|
||
current.total += 1;
|
||
if (entry.contractType === 'canonical_contract') current.canonical += 1;
|
||
if (entry.contractType === 'cw_token' || entry.contractType === 'gas_mirror') current.cw += 1;
|
||
if (entry.contractType.includes('pmm_pool')) current.pools += 1;
|
||
summaryByChain.set(key, current);
|
||
}
|
||
|
||
const generatedAt = new Date().toISOString();
|
||
const jsonPayload = {
|
||
generatedAt,
|
||
sources: [
|
||
'config/smart-contracts-master.json',
|
||
'cross-chain-pmm-lps/config/deployment-status.json',
|
||
],
|
||
entryCount: entries.length,
|
||
entries,
|
||
};
|
||
|
||
const summaryRows = [...summaryByChain.entries()]
|
||
.map(([key, value]) => {
|
||
const [chainId, chainName] = key.split(':');
|
||
const meta = chainMeta(chainId, chainName);
|
||
return `| ${chainId} | ${chainName} | ${value.total} | ${value.canonical} | ${value.cw} | ${value.pools} | ${meta.explorer || 'manual'} |`;
|
||
})
|
||
.join('\n');
|
||
|
||
const sampleRows = entries.slice(0, 80).map((entry) => {
|
||
const explorer = entry.explorer || 'manual';
|
||
return `| ${entry.chainId} | ${entry.chainName} | ${entry.contractType} | ${entry.label} | \`${entry.address}\` | ${entry.verifierKind} | ${entry.automation} | ${explorer} | ${entry.verificationStatus} | ${entry.publicationStatus} |`;
|
||
}).join('\n');
|
||
|
||
const md = `# Contract Verification And Publication Matrix (All Networks)
|
||
|
||
**Generated:** ${generatedAt}
|
||
**Authoritative sources:** \`config/smart-contracts-master.json\`, \`cross-chain-pmm-lps/config/deployment-status.json\`
|
||
|
||
This matrix is the canonical repo-level inventory for **what still needs explorer verification and publication coverage across every network currently tracked in the workspace**.
|
||
|
||
## Meaning
|
||
|
||
- **Verification** = source or deployment metadata is verified on the network explorer used for that chain.
|
||
- **Publication** = the deployment is also reflected in the repo’s public inventories, token mappings, PMM status, and explorer-facing docs/config where applicable.
|
||
- **Pending** means the repo knows the address, but does not yet have a machine-confirmed proof here that explorer verification/publication is complete.
|
||
|
||
## Chain Summary
|
||
|
||
| Chain ID | Chain | Total Entries | Canonical Contracts | cW / Gas Mirrors | PMM Pools | Explorer |
|
||
| --- | --- | ---: | ---: | ---: | ---: | --- |
|
||
${summaryRows}
|
||
|
||
## Required operator path
|
||
|
||
1. **Chain 138 canonical contracts**
|
||
- Run: \`bash scripts/verify/run-contract-verification-with-proxy.sh\`
|
||
- Recheck: \`bash scripts/verify/check-contracts-on-chain-138.sh\`
|
||
2. **Chain 138 DODO v3 pilot**
|
||
- Run: \`bash scripts/verify/verify-dodo-v3-chain138-blockscout.sh\`
|
||
3. **Other EVM chains**
|
||
- Verify on the chain explorer shown below.
|
||
- If the repo owns the deployment, keep token/pool/mapping docs updated after explorer verification.
|
||
4. **Publication closure**
|
||
- Update \`config/smart-contracts-master.json\`, \`cross-chain-pmm-lps/config/deployment-status.json\`, token lists, and any chain-specific runbooks after verification is confirmed.
|
||
|
||
## Inventory sample
|
||
|
||
The JSON report in \`reports/status/contract_verification_publish_matrix.json\` contains the full set. The first 80 rows are shown here for readability.
|
||
|
||
| Chain ID | Chain | Type | Label | Address | Verifier | Automation | Explorer | Verify | Publish |
|
||
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
||
${sampleRows}
|
||
|
||
## Notes
|
||
|
||
- Entries from \`smart-contracts-master.json\` are treated as the canonical deploy inventory.
|
||
- Entries from \`deployment-status.json\` are treated as required publication inventory, even when explorer verification may be external or manual.
|
||
- This matrix does **not** claim every address is already verified; it marks the repo-wide backlog explicitly so the status can be closed chain by chain instead of being lost in prose.
|
||
`;
|
||
|
||
ensureDir(outputJsonPath);
|
||
ensureDir(outputMdPath);
|
||
fs.writeFileSync(outputJsonPath, JSON.stringify(jsonPayload, null, 2) + '\n');
|
||
fs.writeFileSync(outputMdPath, md + '\n');
|
||
|
||
console.log(`Wrote ${entries.length} entries to:`);
|
||
console.log(`- ${outputJsonPath}`);
|
||
console.log(`- ${outputMdPath}`);
|